/*
 * 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;
  }
}
