/*
 * 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.android.run.test;

import com.android.tools.idea.run.ValidationError;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState;
import com.google.idea.blaze.base.run.state.RunConfigurationState;
import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.jdom.Element;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.annotations.Contract;

/** State specific for the android test configuration. */
final class BlazeAndroidTestRunConfigurationState implements RunConfigurationState {

  private static final String RUN_THROUGH_BLAZE_ATTR = "blaze-run-through-blaze";

  public static final int TEST_ALL_IN_MODULE = 0;
  public static final int TEST_ALL_IN_PACKAGE = 1;
  public static final int TEST_CLASS = 2;
  public static final int TEST_METHOD = 3;

  // We reinterpret Android Studio's test mode for running "all tests in a module"
  // (all the tests in the installed test APK) as running all
  // the tests in a rule.
  public static final int TEST_ALL_IN_TARGET = TEST_ALL_IN_MODULE;

  private static final String TESTING_TYPE = "TESTING_TYPE";
  private static final String INSTRUMENTATION_RUNNER_CLASS = "INSTRUMENTATION_RUNNER_CLASS";
  private static final String METHOD_NAME = "METHOD_NAME";
  private static final String CLASS_NAME = "CLASS_NAME";
  private static final String PACKAGE_NAME = "PACKAGE_NAME";
  private static final String EXTRA_OPTIONS = "EXTRA_OPTIONS";

  private int testingType = TEST_ALL_IN_MODULE;
  private String instrumentationRunnerClass = "";
  private String methodName = "";
  private String className = "";
  private String packageName = "";
  private String extraOptions = "";

  // Whether to delegate to 'blaze test'.
  private boolean runThroughBlaze;

  private final BlazeAndroidRunConfigurationCommonState commonState;

  public BlazeAndroidTestRunConfigurationState(String buildSystemName) {
    commonState = new BlazeAndroidRunConfigurationCommonState(buildSystemName, true);
  }

  public BlazeAndroidRunConfigurationCommonState getCommonState() {
    return commonState;
  }

  @Contract(pure = true)
  boolean isRunThroughBlaze() {
    return runThroughBlaze;
  }

  void setRunThroughBlaze(boolean runThroughBlaze) {
    this.runThroughBlaze = runThroughBlaze;
  }

  public int getTestingType() {
    return testingType;
  }

  public void setTestingType(int testingType) {
    this.testingType = testingType;
  }

  public String getInstrumentationRunnerClass() {
    return instrumentationRunnerClass;
  }

  public void setInstrumentationRunnerClass(String instrumentationRunnerClass) {
    this.instrumentationRunnerClass = instrumentationRunnerClass;
  }

  public String getMethodName() {
    return methodName;
  }

  public void setMethodName(String methodName) {
    this.methodName = methodName;
  }

  public String getClassName() {
    return className;
  }

  public void setClassName(String className) {
    this.className = className;
  }

  public String getPackageName() {
    return packageName;
  }

  public void setPackageName(String packageName) {
    this.packageName = packageName;
  }

  public String getExtraOptions() {
    return extraOptions;
  }

  public void setExtraOptions(String extraOptions) {
    this.extraOptions = extraOptions;
  }

  /**
   * We collect errors rather than throwing to avoid missing fatal errors by exiting early for a
   * warning.
   */
  public List<ValidationError> validate(@Nullable AndroidFacet facet) {
    return commonState.validate(facet);
  }

  @Override
  public void readExternal(Element element) throws InvalidDataException {
    commonState.readExternal(element);

    String testingTypeAttribute = element.getAttributeValue(TESTING_TYPE);
    if (!Strings.isNullOrEmpty(testingTypeAttribute)) {
      testingType = Integer.parseInt(testingTypeAttribute);
    }
    instrumentationRunnerClass =
        Strings.nullToEmpty(element.getAttributeValue(INSTRUMENTATION_RUNNER_CLASS));
    methodName = Strings.nullToEmpty(element.getAttributeValue(METHOD_NAME));
    className = Strings.nullToEmpty(element.getAttributeValue(CLASS_NAME));
    packageName = Strings.nullToEmpty(element.getAttributeValue(PACKAGE_NAME));
    extraOptions = Strings.nullToEmpty(element.getAttributeValue(EXTRA_OPTIONS));
    runThroughBlaze = Boolean.parseBoolean(element.getAttributeValue(RUN_THROUGH_BLAZE_ATTR));

    for (Map.Entry<String, String> entry : getLegacyValues(element).entrySet()) {
      String value = entry.getValue();
      switch (entry.getKey()) {
        case TESTING_TYPE:
          if (!Strings.isNullOrEmpty(value)) {
            testingType = Integer.parseInt(value);
          }
          break;
        case INSTRUMENTATION_RUNNER_CLASS:
          instrumentationRunnerClass = Strings.nullToEmpty(value);
          break;
        case METHOD_NAME:
          methodName = Strings.nullToEmpty(value);
          break;
        case CLASS_NAME:
          className = Strings.nullToEmpty(value);
          break;
        case PACKAGE_NAME:
          packageName = Strings.nullToEmpty(value);
          break;
        case EXTRA_OPTIONS:
          extraOptions = Strings.nullToEmpty(value);
          break;
        default:
          break;
      }
    }
  }

  @Override
  public void writeExternal(Element element) throws WriteExternalException {
    commonState.writeExternal(element);

    element.setAttribute(RUN_THROUGH_BLAZE_ATTR, Boolean.toString(runThroughBlaze));
    element.setAttribute(TESTING_TYPE, Integer.toString(testingType));
    element.setAttribute(INSTRUMENTATION_RUNNER_CLASS, instrumentationRunnerClass);
    element.setAttribute(METHOD_NAME, methodName);
    element.setAttribute(CLASS_NAME, className);
    element.setAttribute(PACKAGE_NAME, packageName);
    element.setAttribute(EXTRA_OPTIONS, extraOptions);
  }

  /** Imports legacy values in the old reflective JDOM externalizer manner. Can be removed ~2.0+. */
  private static Map<String, String> getLegacyValues(Element element) {
    Map<String, String> result = Maps.newHashMap();
    for (Element option : element.getChildren("option")) {
      String name = option.getAttributeValue("name");
      String value = option.getAttributeValue("value");
      result.put(name, value);
    }
    return result;
  }

  @Override
  public RunConfigurationStateEditor getEditor(Project project) {
    return new BlazeAndroidTestRunConfigurationStateEditor(commonState.getEditor(project), project);
  }
}
