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

import com.intellij.execution.Location;
import com.intellij.execution.PsiLocation;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.execution.junit.JUnitUtil;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/** Helper functions for getting selected test methods. */
public class TestMethodSelectionUtil {

  /**
   * Get all test methods directly or indirectly selected in the given context. This includes
   * methods selected in the Structure panel, as well as methods the context location is inside of.
   *
   * @param context The context to get selected test methods from.
   * @param allMustMatch If true, will return null if any selected elements are not test methods.
   * @return A list of test methods (with at least one element), or null if:
   *     <ul>
   *     <li>There are no selected test methods
   *     <li>{@code allMustMatch} is true, but elements other than test methods are selected
   *     </ul>
   *
   * @see #getDirectlySelectedMethods(ConfigurationContext, boolean)
   * @see #getIndirectlySelectedMethod(ConfigurationContext)
   */
  @Nullable
  public static List<PsiMethod> getSelectedMethods(
      @NotNull ConfigurationContext context, boolean allMustMatch) {
    List<PsiMethod> directlySelectedMethods = getDirectlySelectedMethods(context, allMustMatch);
    if (directlySelectedMethods != null && directlySelectedMethods.size() > 0) {
      return directlySelectedMethods;
    }
    if (allMustMatch && JUnitConfigurationUtil.isMultipleElementsSelected(context)) {
      return null;
    }
    PsiMethod indirectlySelectedMethod = getIndirectlySelectedMethod(context);
    if (indirectlySelectedMethod != null) {
      return Collections.singletonList(indirectlySelectedMethod);
    }
    return null;
  }

  /**
   * Get all test methods directly or indirectly selected in the given context. This includes
   * methods selected in the Structure panel, as well as methods the context location is inside of.
   *
   * @param context The context to get selected test methods from.
   * @return A list of test methods (with at least one element), or null if:
   *     <ul>
   *     <li>There are no selected test methods
   *     <li>Any elements other than test methods are selected
   *     </ul>
   *
   * @see #getDirectlySelectedMethods(ConfigurationContext, boolean)
   * @see #getIndirectlySelectedMethod(ConfigurationContext)
   */
  @Nullable
  public static List<PsiMethod> getSelectedMethods(@NotNull ConfigurationContext context) {
    return getSelectedMethods(context, true);
  }

  /**
   * Get all test methods directly selected in the given context. This includes, for example,
   * methods selected from the Structure panel. It does not include methods the context location is
   * inside of. Note that methods may belong to different classes (possible if methods are selected
   * from the Project panel with "Show Members" checked), and methods in abstract classes are not
   * returned.
   *
   * @param context The context to get selected test methods from.
   * @param allMustMatch If true, will return null if any selected elements are not test methods.
   * @return A list of test methods (possibly empty), or null if:
   *     <ul>
   *     <li>There is no selection
   *     <li>{@code allMustMatch} is true, but elements other than test methods are selected
   *     </ul>
   */
  @Nullable
  public static List<PsiMethod> getDirectlySelectedMethods(
      @NotNull ConfigurationContext context, boolean allMustMatch) {
    final DataContext dataContext = context.getDataContext();
    PsiElement[] elements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext);
    if (elements == null) {
      return null;
    }
    List<PsiMethod> methods = new ArrayList<>();
    for (PsiElement element : elements) {
      if (element instanceof PsiMethod) {
        PsiMethod method = (PsiMethod) element;
        if (JUnitUtil.isTestMethod(PsiLocation.fromPsiElement(method))) {
          methods.add(method);
        } else if (allMustMatch) {
          return null;
        }
      } else if (allMustMatch) {
        return null;
      }
    }
    return methods;
  }

  /**
   * Get a test method which is considered selected in the given context, belonging to a
   * non-abstract class. The context location may be the method itself, or anywhere inside the
   * method.
   *
   * @param context The context to search for a test method in.
   * @return A test method, or null if none are found.
   */
  @Nullable
  public static PsiMethod getIndirectlySelectedMethod(@NotNull ConfigurationContext context) {
    final Location<?> contextLocation = context.getLocation();
    if (contextLocation == null) {
      return null;
    }
    Iterator<Location<PsiMethod>> locationIterator =
        contextLocation.getAncestors(PsiMethod.class, false);
    while (locationIterator.hasNext()) {
      Location<PsiMethod> methodLocation = locationIterator.next();
      if (JUnitUtil.isTestMethod(methodLocation)) {
        return methodLocation.getPsiElement();
      }
    }
    return null;
  }
}
