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

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.async.process.ExternalTask;
import com.google.idea.blaze.base.command.BlazeCommand;
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.command.buildresult.BuildResultHelper;
import com.google.idea.blaze.base.issueparser.IssueOutputLineProcessor;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.projectview.ProjectViewManager;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner;
import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.ScopedTask;
import com.google.idea.blaze.base.scope.output.StatusOutput;
import com.google.idea.blaze.base.scope.scopes.BlazeConsoleScope;
import com.google.idea.blaze.base.scope.scopes.IssuesScope;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.util.SaveUtil;
import com.google.idea.common.experiments.BoolExperiment;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.jetbrains.cidr.execution.CidrCommandLineState;
import java.io.File;

/** CLion-specific handler for {@link BlazeCommandRunConfiguration}s. */
public class BlazeCidrRunConfigurationRunner implements BlazeCommandRunConfigurationRunner {

  private static final Logger LOG = Logger.getInstance(ExternalTask.class);

  private static final BoolExperiment FORCE_DEBUG_BUILD_FOR_DEBUGGING_TEST =
      new BoolExperiment("clwb.force.debug.build.for.debugging.test", true);

  private final BlazeCommandRunConfiguration configuration;

  /** Calculated during the before-run task, and made available to the debugger. */
  File executableToDebug = null;

  BlazeCidrRunConfigurationRunner(BlazeCommandRunConfiguration configuration) {
    this.configuration = configuration;
  }

  @Override
  public RunProfileState getRunProfileState(Executor executor, ExecutionEnvironment env) {
    return new CidrCommandLineState(env, new BlazeCidrLauncher(configuration, this, env));
  }

  @Override
  public boolean executeBeforeRunTask(ExecutionEnvironment environment) {
    if (!isDebugging(environment)) {
      return true;
    }
    try {
      File executable = getExecutableToDebug();
      if (executable != null) {
        executableToDebug = executable;
        return true;
      }
    } catch (ExecutionException e) {
      LOG.error(e.getMessage());
    }
    return false;
  }

  private static boolean isDebugging(ExecutionEnvironment environment) {
    Executor executor = environment.getExecutor();
    return executor instanceof DefaultDebugExecutor;
  }

  /**
   * Builds blaze C/C++ target in debug mode, and returns the output build artifact.
   *
   * @throws ExecutionException if no unique output artifact was found.
   */
  private File getExecutableToDebug() throws ExecutionException {
    final Project project = configuration.getProject();
    final BlazeCommandRunConfigurationCommonState handlerState =
        (BlazeCommandRunConfigurationCommonState) configuration.getHandler().getState();
    final WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project);
    final ProjectViewSet projectViewSet =
        ProjectViewManager.getInstance(project).getProjectViewSet();

    BuildResultHelper buildResultHelper = BuildResultHelper.forFiles(file -> true);

    final ListenableFuture<Void> buildOperation =
        BlazeExecutor.submitTask(
            project,
            new ScopedTask() {
              @Override
              protected void execute(BlazeContext context) {
                context
                    .push(new IssuesScope(project))
                    .push(new BlazeConsoleScope.Builder(project).build());

                context.output(new StatusOutput("Building debug binary"));

                BlazeCommand.Builder command =
                    BlazeCommand.builder(
                            Blaze.getBuildSystemProvider(project).getBinaryPath(),
                            BlazeCommandName.BUILD)
                        .addTargets(configuration.getTarget())
                        .addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
                        .addBlazeFlags(handlerState.getBlazeFlags())
                        .addBlazeFlags(buildResultHelper.getBuildFlags());

                // If we are trying to debug, make sure we are building in debug mode.
                // This can cause a rebuild, so it is a heavyweight setting.
                if (FORCE_DEBUG_BUILD_FOR_DEBUGGING_TEST.getValue()) {
                  command.addBlazeFlags("-c", "dbg");
                }

                ExternalTask.builder(workspaceRoot)
                    .addBlazeCommand(command.build())
                    .context(context)
                    .stderr(
                        buildResultHelper.stderr(
                            new IssueOutputLineProcessor(project, context, workspaceRoot)))
                    .build()
                    .run();
              }
            });

    try {
      SaveUtil.saveAllFiles();
      buildOperation.get();
    } catch (InterruptedException | java.util.concurrent.ExecutionException e) {
      throw new ExecutionException(e);
    }
    ImmutableList<File> outputArtifacts = buildResultHelper.getBuildArtifacts();
    if (outputArtifacts.isEmpty()) {
      throw new ExecutionException(
          String.format("No output artifacts found when building %s", configuration.getTarget()));
    }
    if (outputArtifacts.size() > 1) {
      throw new ExecutionException(
          String.format(
              "More than 1 executable was produced when building %s; don't know which one to debug",
              configuration.getTarget()));
    }
    LocalFileSystem.getInstance().refreshIoFiles(outputArtifacts);
    return Iterables.getOnlyElement(outputArtifacts);
  }
}
