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

import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.Location;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.testframework.AbstractTestProxy;
import com.intellij.execution.testframework.TestFrameworkRunningModel;
import com.intellij.execution.testframework.actions.AbstractRerunFailedTestsAction;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentContainer;
import com.intellij.psi.search.GlobalSearchScope;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/** Re-run failed tests. */
public class BlazeRerunFailedTestsAction extends AbstractRerunFailedTestsAction {

  private final BlazeTestEventsHandler eventsHandler;

  public BlazeRerunFailedTestsAction(
      BlazeTestEventsHandler eventsHandler, ComponentContainer componentContainer) {
    super(componentContainer);
    this.eventsHandler = eventsHandler;
  }

  @Override
  @Nullable
  protected MyRunProfile getRunProfile(ExecutionEnvironment environment) {
    final TestFrameworkRunningModel model = getModel();
    if (model == null) {
      return null;
    }
    BlazeCommandRunConfiguration config =
        (BlazeCommandRunConfiguration) model.getProperties().getConfiguration();
    return new BlazeRerunTestRunProfile(config.clone());
  }

  class BlazeRerunTestRunProfile extends MyRunProfile {

    private final BlazeCommandRunConfiguration configuration;

    BlazeRerunTestRunProfile(BlazeCommandRunConfiguration configuration) {
      super(configuration);
      this.configuration = configuration;
    }

    @Override
    public Module[] getModules() {
      return Module.EMPTY_ARRAY;
    }

    @Nullable
    @Override
    public RunProfileState getState(Executor executor, ExecutionEnvironment environment)
        throws ExecutionException {
      BlazeCommandRunConfigurationCommonState handlerState =
          configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
      if (handlerState == null || !BlazeCommandName.TEST.equals(handlerState.getCommand())) {
        return null;
      }
      Project project = getProject();
      List<Location<?>> locations =
          getFailedTests(project)
              .stream()
              .map((test) -> toLocation(project, test))
              .filter(Objects::nonNull)
              .collect(Collectors.toList());
      String testFilter = eventsHandler.getTestFilter(getProject(), locations);
      if (testFilter == null) {
        return null;
      }
      List<String> blazeFlags = setTestFilter(handlerState.getBlazeFlags(), testFilter);
      handlerState.setBlazeFlags(blazeFlags);
      return configuration.getState(executor, environment);
    }

    @Nullable
    private Location<?> toLocation(Project project, AbstractTestProxy test) {
      return test.getLocation(project, GlobalSearchScope.allScope(project));
    }

    /** Replaces existing test_filter flag, or appends if none exists. */
    private List<String> setTestFilter(List<String> flags, String testFilter) {
      List<String> copy = new ArrayList<>(flags);
      for (int i = 0; i < copy.size(); i++) {
        String flag = copy.get(i);
        if (flag.startsWith(BlazeFlags.TEST_FILTER)) {
          copy.set(i, testFilter);
          return copy;
        }
      }
      copy.add(testFilter);
      return copy;
    }
  }
}
