/*
 * Copyright 2013-present Facebook, Inc.
 *
 * 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.facebook.buck.cli;

import com.facebook.buck.command.Build;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.rules.BinaryBuildRule;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.shell.DefaultShellStep;
import com.facebook.buck.shell.ShellStep;
import com.facebook.buck.util.Verbosity;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;

import java.io.IOException;

public class RunCommand extends AbstractCommandRunner<RunCommandOptions> {

  public RunCommand(CommandRunnerParams params) {
    super(params);
  }

  @Override
  String getUsageIntro() {
    return "runs the specified target as a command, with provided args";
  }

  @Override
  int runCommandWithOptionsInternal(RunCommandOptions options)
      throws IOException, InterruptedException {
    if (!options.hasTargetSpecified()) {
      console.printBuildFailure("No target given to run");
      console.getStdOut().println("buck run <target> <arg1> <arg2>...");
      return 1;
    }

    // Make sure the target is built.
    BuildCommand buildCommand = new BuildCommand(getCommandRunnerParams());
    BuildCommandOptions buildCommandOptions = new BuildCommandOptions(options.getBuckConfig());
    buildCommandOptions.setArguments(ImmutableList.of(options.getTarget()));
    int exitCode = buildCommand.runCommandWithOptions(buildCommandOptions);
    if (exitCode != 0) {
      return exitCode;
    }

    String targetName = options.getTarget();
    BuildTarget target = Iterables.getOnlyElement(getBuildTargets(ImmutableSet.of(targetName)));

    Build build = buildCommand.getBuild();
    BuildRule targetRule = build.getActionGraph().findBuildRuleByTarget(target);
    BinaryBuildRule binaryBuildRule = null;
    if (targetRule instanceof BinaryBuildRule) {
      binaryBuildRule = (BinaryBuildRule) targetRule;
    }
    if (binaryBuildRule == null) {
      console.printBuildFailure(
          "target " + targetName + " is not a binary rule (only binary rules can be `run`)");
      return 1;
    }

    // Ideally, we would take fullCommand, disconnect from NailGun, and run the command in the
    // user's shell. Currently, if you use `buck run` with buckd and ctrl-C to kill the command
    // being run, occasionally I get the following error when I try to run `buck run` again:
    //
    //   Daemon is busy, please wait or run "buckd --kill" to terminate it.
    //
    // Clearly something bad has happened here. If you are using `buck run` to start up a server
    // or some other process that is meant to "run forever," then it's pretty common to do:
    // `buck run`, test server, hit ctrl-C, edit server code, repeat. This should not wedge buckd.
    ImmutableList<String> fullCommand = new ImmutableList.Builder<String>()
        .addAll(binaryBuildRule.getExecutableCommand(getProjectFilesystem()))
        .addAll(options.getTargetArguments())
        .build();

    ShellStep step = new DefaultShellStep(fullCommand) {
      // Print the output from the step directly to stdout and stderr rather than buffering it and
      // printing it as two individual strings. This preserves the expected behavior where output
      // written to stdout and stderr may be interleaved when displayed in a terminal.
      @Override
      protected boolean shouldFlushStdOutErrAsProgressIsMade(Verbosity verbosity) {
        return true;
      }
    };
    return step.execute(build.getExecutionContext());
  }

  @Override
  RunCommandOptions createOptions(BuckConfig buckConfig) {
    return new RunCommandOptions(buckConfig);
  }
}
