/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.idea.blaze.base.model.primitives;

import com.google.common.collect.ImmutableMap;

import java.util.Arrays;
import java.util.List;

/**
 * Wrapper around a string for a blaze kind (android_library, android_test...)
 */
public enum Kind {

  ANDROID_BINARY("android_binary", LanguageClass.ANDROID),
  ANDROID_LIBRARY("android_library", LanguageClass.ANDROID),
  ANDROID_TEST("android_test", LanguageClass.ANDROID),
  ANDROID_ROBOLECTRIC_TEST("android_robolectric_test", LanguageClass.ANDROID),
  JAVA_LIBRARY("java_library", LanguageClass.JAVA),
  JAVA_TEST("java_test", LanguageClass.JAVA),
  JAVA_BINARY("java_binary", LanguageClass.JAVA),
  JAVA_IMPORT("java_import", LanguageClass.JAVA),
  JAVA_TOOLCHAIN("java_toolchain", LanguageClass.JAVA),
  PROTO_LIBRARY("proto_library", LanguageClass.JAVA), // The LanguageClass might have to change if we support other languages
  JAVA_PLUGIN("java_plugin", LanguageClass.JAVA),
  ANDROID_RESOURCES("android_resources", LanguageClass.ANDROID),
  CC_LIBRARY("cc_library", LanguageClass.C),
  CC_BINARY("cc_binary", LanguageClass.C),
  CC_TEST("cc_test", LanguageClass.C),
  CC_INC_LIBRARY("cc_inc_library", LanguageClass.C),
  CC_TOOLCHAIN("cc_toolchain", LanguageClass.C),
  JAVA_WRAP_CC("java_wrap_cc", LanguageClass.JAVA),
  GWT_APPLICATION("gwt_application", LanguageClass.JAVA),
  GWT_HOST("gwt_host", LanguageClass.JAVA),
  GWT_MODULE("gwt_module", LanguageClass.JAVA),
  GWT_TEST("gwt_test", LanguageClass.JAVA),
  ;

  static final ImmutableMap<String, Kind> STRING_TO_KIND = makeStringToKindMap();

  private static ImmutableMap<String, Kind> makeStringToKindMap() {
    ImmutableMap.Builder<String, Kind> result = ImmutableMap.builder();
    for (Kind kind : Kind.values()) {
      result.put(kind.toString(), kind);
    }
    return result.build();
  }

  public static Kind fromString(String kindString) {
    return STRING_TO_KIND.get(kindString);
  }

  private final String kind;
  private final LanguageClass languageClass;

  Kind(String kind, LanguageClass languageClass) {
    this.kind = kind;
    this.languageClass = languageClass;
  }

  @Override
  public String toString() {
    return kind;
  }

  public LanguageClass getLanguageClass() {
    return languageClass;
  }

  public boolean isOneOf(Kind... kinds) {
    return isOneOf(Arrays.asList(kinds));
  }

  public boolean isOneOf(List<Kind> kinds) {
    for (Kind kind : kinds) {
      if (this.equals(kind)) {
        return true;
      }
    }
    return false;
  }
}
