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

import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.run.smrunner.BlazeTestEventsHandler;
import com.google.idea.blaze.base.run.smrunner.BlazeXmlSchema.TestSuite;
import com.google.idea.blaze.java.run.producers.BlazeJUnitTestFilterFlags;
import com.intellij.execution.Location;
import com.intellij.execution.testframework.JavaTestLocator;
import com.intellij.execution.testframework.sm.runner.SMTestLocator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.util.io.URLUtil;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

/** Provides java-specific methods needed by the SM-runner test UI. */
public class BlazeJavaTestEventsHandler extends BlazeTestEventsHandler {

  @Override
  protected EnumSet<Kind> handledKinds() {
    return EnumSet.of(Kind.JAVA_TEST, Kind.ANDROID_ROBOLECTRIC_TEST, Kind.GWT_TEST);
  }

  /** Overridden to support parameterized tests, which use nested test_suite XML elements. */
  @Override
  public boolean ignoreSuite(TestSuite suite) {
    if (suite.testSuites.isEmpty()) {
      return false;
    }
    for (TestSuite child : suite.testSuites) {
      // target/class names are fully-qualified; unqualified names denote parameterized methods
      if (!child.name.contains(".")) {
        return false;
      }
    }
    return true;
  }

  @Override
  public SMTestLocator getTestLocator() {
    return JavaTestLocator.INSTANCE;
  }

  @Override
  public String suiteLocationUrl(@Nullable Kind kind, String name) {
    return JavaTestLocator.SUITE_PROTOCOL + URLUtil.SCHEME_SEPARATOR + name;
  }

  @Override
  public String testLocationUrl(
      @Nullable Kind kind, String parentSuite, String name, @Nullable String classname) {
    if (classname == null) {
      return null;
    }
    String classComponent = JavaTestLocator.TEST_PROTOCOL + URLUtil.SCHEME_SEPARATOR + classname;
    String parameterComponent = extractParameterComponent(name);
    if (parameterComponent != null) {
      return classComponent + "." + parentSuite + parameterComponent;
    }
    return classComponent + "." + name;
  }

  @Nullable
  private static String extractParameterComponent(String name) {
    if (name.startsWith("[") && name.contains("]")) {
      return name.substring(0, name.indexOf(']') + 1);
    }
    return null;
  }

  @Override
  public String suiteDisplayName(@Nullable Kind kind, String rawName) {
    String name = StringUtil.trimEnd(rawName, '.');
    int lastPointIx = name.lastIndexOf('.');
    return lastPointIx != -1 ? name.substring(lastPointIx + 1, name.length()) : name;
  }

  @Nullable
  @Override
  public String getTestFilter(Project project, List<Location<?>> testLocations) {
    Map<PsiClass, Collection<Location<?>>> failedClassesAndMethods = new HashMap<>();
    for (Location<?> location : testLocations) {
      appendTest(failedClassesAndMethods, location);
    }
    String filter =
        BlazeJUnitTestFilterFlags.testFilterForClassesAndMethods(failedClassesAndMethods);
    return filter != null ? BlazeFlags.TEST_FILTER + "=" + filter : null;
  }

  private static void appendTest(Map<PsiClass, Collection<Location<?>>> map, Location<?> location) {
    PsiElement psi = location.getPsiElement();
    if (psi instanceof PsiClass) {
      map.computeIfAbsent((PsiClass) psi, k -> new HashSet<>());
      return;
    }
    if (!(psi instanceof PsiMethod)) {
      return;
    }
    PsiClass psiClass = ((PsiMethod) psi).getContainingClass();
    if (psiClass == null) {
      return;
    }
    map.computeIfAbsent(psiClass, k -> new HashSet<>()).add(location);
  }
}
