/*
 * 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.Iterables;
import com.google.common.collect.Lists;
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.async.process.LineProcessingOutputStream;
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.ExperimentalShowArtifactsLineProcessor;
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;
import java.util.List;

/** 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();

    final List<File> outputArtifacts = Lists.newArrayList();
    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.getBuildSystem(project), BlazeCommandName.BUILD)
                        .addTargets(configuration.getTarget())
                        .addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
                        .addBlazeFlags(handlerState.getBlazeFlags());

                command.addBlazeFlags("--experimental_show_artifacts");

                // 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(
                        LineProcessingOutputStream.of(
                            new ExperimentalShowArtifactsLineProcessor(outputArtifacts),
                            new IssueOutputLineProcessor(project, context, workspaceRoot)))
                    .build()
                    .run();
              }
            });

    try {
      SaveUtil.saveAllFiles();
      buildOperation.get();
    } catch (InterruptedException | java.util.concurrent.ExecutionException e) {
      throw new ExecutionException(e);
    }
    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);
  }
}
