/*
 * Copyright 2017 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.python.run.smrunner;

import com.google.common.base.Joiner;
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.intellij.execution.Location;
import com.intellij.execution.testframework.sm.runner.SMTestLocator;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFunction;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import javax.annotation.Nullable;

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

  @Override
  protected EnumSet<Kind> handledKinds() {
    return EnumSet.of(Kind.PY_TEST);
  }

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

  @Override
  public String testDisplayName(@Nullable Kind kind, String rawName) {
    int lastDotIndex = rawName.lastIndexOf('.');
    return lastDotIndex != -1 ? rawName.substring(lastDotIndex + 1) : rawName;
  }

  @Nullable
  @Override
  public String getTestFilter(Project project, List<Location<?>> testLocations) {
    // python test runner parses filters of the form "class1.method1 class2.method2 ..."
    List<String> filters = new ArrayList<>();
    for (Location<?> location : testLocations) {
      String filter = getFilter(location.getPsiElement());
      if (filter != null) {
        filters.add(filter);
      }
    }
    if (filters.isEmpty()) {
      return null;
    }
    return String.format("%s=%s", BlazeFlags.TEST_FILTER, Joiner.on(' ').join(filters));
  }

  @Nullable
  private static String getFilter(PsiElement psiElement) {
    if (psiElement instanceof PyClass) {
      return ((PyClass) psiElement).getName();
    }
    if (!(psiElement instanceof PyFunction)) {
      return null;
    }
    PyClass pyClass = ((PyFunction) psiElement).getContainingClass();
    if (pyClass == null) {
      return null;
    }
    String methodName = ((PyFunction) psiElement).getName();
    String className = pyClass.getName();
    return methodName != null && className != null ? className + "." + methodName : null;
  }

}
