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

import com.facebook.buck.java.JavaBinaryRule;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.rules.BinaryBuildRule;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.Buildable;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.util.HumanReadableException;
import com.facebook.buck.util.ProjectFilesystem;
import com.facebook.buck.util.Verbosity;
import com.facebook.buck.util.environment.Platform;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public abstract class AbstractGenruleStep extends ShellStep {

  /**
   * Matches either a relative or fully-qualified build target wrapped in <tt>${}</tt>, unless the
   * <code>$</code> is preceded by a backslash.
   *
   * Given the input: $(exe //foo:bar), capturing groups are
   * 1: $(exe //foo:bar)
   * 2: exe
   * 3: //foo:bar
   * 4: //foo
   * 5: :bar
   * If we match against $(location :bar), the capturing groups are:
   * 1: $(location :bar)
   * 2: location
   * 3: :bar
   * 4: null
   * 5: :bar
   */
  @VisibleForTesting
  static final Pattern BUILD_TARGET_PATTERN = Pattern.compile(
      // We want a negative lookbehind to ensure we don't have a '\$', which is why this starts off
      // in such an interesting way.
      "(?<!\\\\)(\\$\\((exe|location)\\s+((\\/\\/[^:]*)?(:[^\\)]+))\\))"
  );

  private final BuildRule buildRule;
  private final CommandString commandString;
  private final ImmutableSortedSet<BuildRule> depsToSubstituteInCommandString;

  public AbstractGenruleStep(BuildRule buildRule,
      CommandString commandString,
      Set<BuildRule> depsToSubstituteInCommandString) {
    this.buildRule = Preconditions.checkNotNull(buildRule);
    this.commandString = Preconditions.checkNotNull(commandString);
    this.depsToSubstituteInCommandString = ImmutableSortedSet.copyOf(
        depsToSubstituteInCommandString);
  }

  public static class CommandString {
    private Optional<String> cmd;
    private Optional<String> bash;
    private Optional<String> cmdExe;

    public CommandString(Optional<String> cmd, Optional<String> bash, Optional<String> cmdExe) {
      this.cmd = Preconditions.checkNotNull(cmd);
      this.bash = Preconditions.checkNotNull(bash);
      this.cmdExe = Preconditions.checkNotNull(cmdExe);
    }
  }

  private String getFullyQualifiedName() {
    return buildRule.getFullyQualifiedName();
  }

  @Override
  public String getShortName() {
    return "genrule";
  }

  @Override
  protected ImmutableList<String> getShellCommandInternal(ExecutionContext context) {
    // The priority sequence is
    //   "cmd.exe /c winCommand" (Windows Only)
    //   "/bin/bash -c shCommand" (Non-windows Only)
    //   "(/bin/bash -c) or (cmd.exe /c) cmd" (All platforms)
    String command;
    if (context.getPlatform() == Platform.WINDOWS) {
      String commandInUse;
      if (commandString.cmdExe.isPresent()) {
        commandInUse = commandString.cmdExe.get();
      } else if (commandString.cmd.isPresent()) {
        commandInUse = commandString.cmd.get();
      } else {
        throw new HumanReadableException("You must specify either cmd_exe or cmd for genrule %s.",
            getFullyQualifiedName());
      }
      command = replaceMatches(context.getProjectFilesystem(), commandInUse);
      return ImmutableList.of("cmd.exe", "/c", command);
    } else {
      String commandInUse;
      if (commandString.bash.isPresent()) {
        commandInUse = commandString.bash.get();
      } else if (commandString.cmd.isPresent()) {
        commandInUse = commandString.cmd.get();
      } else {
        throw new HumanReadableException("You must specify either bash or cmd for genrule %s.",
            getFullyQualifiedName());
      }
      command = replaceMatches(context.getProjectFilesystem(), commandInUse);
      return ImmutableList.of("/bin/bash", "-ec", command);
    }
  }

  @Override
  public ImmutableMap<String, String> getEnvironmentVariables(ExecutionContext context) {
    ImmutableMap.Builder<String, String> environmentVariablesBuilder = ImmutableMap.builder();

    addEnvironmentVariables(context, environmentVariablesBuilder);

    return environmentVariablesBuilder.build();
  }

  abstract protected void addEnvironmentVariables(ExecutionContext context,
      ImmutableMap.Builder<String, String> environmentVariablesBuilder);

  @Override
  protected boolean shouldPrintStderr(Verbosity verbosity) {
    return true;
  }

  /**
   * @return the cmd with binary and location build targets interpolated as either commands or the
   * location of the outputs of those targets.
   */
  @VisibleForTesting
  String replaceMatches(ProjectFilesystem filesystem, String command) {
    Matcher matcher = BUILD_TARGET_PATTERN.matcher(command);
    StringBuffer buffer = new StringBuffer();
    Map<String, BuildRule> fullyQualifiedNameToBuildRule = null;
    while (matcher.find()) {
      if (fullyQualifiedNameToBuildRule == null) {
        fullyQualifiedNameToBuildRule = Maps.newHashMap();
        for (BuildRule dep : depsToSubstituteInCommandString) {
          fullyQualifiedNameToBuildRule.put(dep.getFullyQualifiedName(), dep);
        }
      }

      String buildTarget = matcher.group(3);
      String base = matcher.group(4);
      if (base == null) {
        // This is a relative build target, so make it fully qualified.
        BuildTarget myBuildTarget = buildRule.getBuildTarget();
        buildTarget = String.format("//%s%s", myBuildTarget.getBasePath(), buildTarget);
      }
      BuildRule matchingRule = fullyQualifiedNameToBuildRule.get(buildTarget);
      if (matchingRule == null) {
        throw new HumanReadableException("No dep named %s for %s %s, cmd was %s",
            buildTarget, buildRule.getType().getName(), getFullyQualifiedName(), command);
      }

      String replacement;
      Buildable matchingBuildable = matchingRule.getBuildable();
      switch (matcher.group(2)) {
        case "exe":
          replacement = getExecutableReplacementFrom(filesystem, command, matchingBuildable);
          break;

        case "location":
          replacement = getLocationReplacementFrom(filesystem, matchingBuildable);
          break;

        default:
          throw new HumanReadableException("Unable to determine replacement for '%s' in target %s",
              matcher.group(2), getFullyQualifiedName());
      }

      // `replacement` may contain Windows style directory separator backslash (\), which will be
      // considered as escape character. Escape them.
      matcher.appendReplacement(buffer, replacement.replace("\\", "\\\\").replace("$", "\\$"));
    }
    matcher.appendTail(buffer);
    return buffer.toString();
  }

  private String getLocationReplacementFrom(ProjectFilesystem filesystem, Buildable matchingRule) {
    return filesystem.getPathRelativizer().apply(matchingRule.getPathToOutputFile());
  }

  /**
   * A build rule can be executable in one of two ways: either by being a file with the executable
   * bit set, or by the rule being a {@link com.facebook.buck.rules.BinaryBuildRule}.
   *
   * @param filesystem The project file system to resolve files with.
   * @param cmd The command being executed.
   * @param matchingRule The BuildRule which may or may not be an executable.
   * @return A string which can be inserted to cause matchingRule to be executed.
   */
  private String getExecutableReplacementFrom(
      ProjectFilesystem filesystem,
      String cmd,
      Buildable matchingRule) {
    if (matchingRule instanceof BinaryBuildRule) {
      BinaryBuildRule binaryBuildRule = (BinaryBuildRule) matchingRule;
      if (binaryBuildRule instanceof JavaBinaryRule) {
        List<String> jvmArgs = Lists.newArrayListWithCapacity(4);
        jvmArgs.add("-Djava.io.tmpdir=$TMP");
        return ((JavaBinaryRule) binaryBuildRule).getExecutableCommand(filesystem, jvmArgs);
      } else {
        return binaryBuildRule.getExecutableCommand(filesystem);
      }
    }

    File output = filesystem.getFileForRelativePath(matchingRule.getPathToOutputFile());
    if (output != null && output.exists() && output.canExecute()) {
      return output.getAbsolutePath();
    }

    throw new HumanReadableException(
        "%s must correspond to a binary rule or file in %s for %s %s",
        matchingRule,
        cmd,
        buildRule.getType().getName(),
        getFullyQualifiedName());
  }
}
