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

import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
import com.google.idea.blaze.base.run.smrunner.BlazeTestEventsHandler;
import com.google.idea.blaze.base.run.smrunner.SmRunnerUtils;
import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.intellij.execution.Location;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;

/**
 * Handles the specific case where the user creates a run configuration by selecting test suites /
 * classes / methods from the test UI tree.
 *
 * <p>In this special case we already know the blaze target string, and only need to apply a filter
 * to the existing configuration. Delegates language-specific filter calculation to {@link
 * BlazeTestEventsHandler}.
 */
public class BlazeFilterExistingRunConfigurationProducer
    extends BlazeRunConfigurationProducer<BlazeCommandRunConfiguration> {

  public BlazeFilterExistingRunConfigurationProducer() {
    super(BlazeCommandRunConfigurationType.getInstance());
  }

  @Override
  protected boolean doSetupConfigFromContext(
      BlazeCommandRunConfiguration configuration,
      ConfigurationContext context,
      Ref<PsiElement> sourceElement) {
    String testFilter = getTestFilter(context);
    if (testFilter == null) {
      return false;
    }
    BlazeCommandRunConfigurationCommonState handlerState =
        configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
    if (handlerState == null || !BlazeCommandName.TEST.equals(handlerState.getCommand())) {
      return false;
    }
    // replace old test filter flag if present
    List<String> flags = new ArrayList<>(handlerState.getBlazeFlags());
    flags.removeIf((flag) -> flag.startsWith(BlazeFlags.TEST_FILTER));
    flags.add(testFilter);
    handlerState.setBlazeFlags(flags);
    configuration.setName(configuration.getName() + " (filtered)");
    configuration.setNameChangedByUser(true);
    return true;
  }

  @Override
  protected boolean doIsConfigFromContext(
      BlazeCommandRunConfiguration configuration, ConfigurationContext context) {
    String testFilter = getTestFilter(context);
    if (testFilter == null) {
      return false;
    }
    BlazeCommandRunConfigurationCommonState handlerState =
        configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);

    return handlerState != null
        && Objects.equals(handlerState.getCommand(), BlazeCommandName.TEST)
        && Objects.equals(testFilter, handlerState.getTestFilterFlag());
  }

  @Nullable
  private static String getTestFilter(ConfigurationContext context) {
    RunConfiguration base = context.getOriginalConfiguration(null);
    if (!(base instanceof BlazeCommandRunConfiguration)) {
      return null;
    }
    TargetExpression target = ((BlazeCommandRunConfiguration) base).getTarget();
    if (target == null) {
      return null;
    }
    BlazeTestEventsHandler testEventsHandler =
        BlazeTestEventsHandler.getHandlerForTarget(context.getProject(), target);
    if (testEventsHandler == null) {
      return null;
    }
    List<Location<?>> selectedElements = SmRunnerUtils.getSelectedSmRunnerTreeElements(context);
    if (selectedElements.isEmpty()) {
      return null;
    }
    return testEventsHandler.getTestFilter(context.getProject(), selectedElements);
  }
}
