// Copyright 2018 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.devtools.build.importdeps;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.io.MoreFiles.asCharSink;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.devtools.build.lib.view.proto.Deps.Dependencies;
import com.google.devtools.common.options.Converter;
import com.google.devtools.common.options.EnumConverter;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.OptionsParsingException;
import com.google.devtools.common.options.ShellQuotedParamsFilePreProcessor;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

/**
 * A checker that checks the completeness of the dependencies of an import target (java_import or
 * aar_import). If incomplete, it prints out the list of missing class names to the output file.
 */
public class Main {

  /** Command line options. */
  public static class Options extends OptionsBase {
    @Option(
      name = "input",
      allowMultiple = true,
      defaultValue = "",
      category = "input",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      converter = ExistingPathConverter.class,
      abbrev = 'i',
      help = "Input jars with classes to check the completeness of their dependencies."
    )
    public List<Path> inputJars;

    @Option(
      name = "directdep",
      allowMultiple = true,
      defaultValue = "",
      category = "input",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      converter = ExistingPathConverter.class,
      help = "Subset of Jars listed in --classpath_entry that --input Jars are allowed to depend "
          + "on directly."
    )
    public List<Path> directClasspath;

    @Option(
      name = "classpath_entry",
      allowMultiple = true,
      defaultValue = "",
      category = "input",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      converter = ExistingPathConverter.class,
      help =
          "Ordered classpath (Jar) to resolve symbols in the --input jars, like javac's -cp flag."
    )
    public List<Path> fullClasspath;

    @Option(
      name = "bootclasspath_entry",
      allowMultiple = true,
      defaultValue = "",
      category = "input",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      converter = ExistingPathConverter.class,
      help =
          "Bootclasspath that was used to compile the --input Jar with, like javac's "
              + "-bootclasspath_entry flag (required)."
    )
    public List<Path> bootclasspath;

    @Option(
        name = "output",
        defaultValue = "null",
        category = "output",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN},
        converter = PathConverter.class,
        help = "Output path to save the result.")
    public Path output;

    @Option(
        name = "jdeps_output",
        defaultValue = "null",
        category = "output",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN},
        converter = PathConverter.class,
        help = "Output path to save the result.")
    public Path jdepsOutput;

    @Option(
        name = "rule_label",
        defaultValue = "",
        category = "output",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN},
        help = "The rule label of the current target under analysis.")
    public String ruleLabel;

    @Option(
      name = "checking_mode",
      defaultValue = "WARNING",
      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
      effectTags = {OptionEffectTag.UNKNOWN},
      converter = CheckingModeConverter.class,
      help = "Controls the behavior of the checker."
    )
    public CheckingMode checkingMode;
  }

  /** A randomly picked large exit code to avoid collision with other common exit codes. */
  private static final int DEPS_ERROR_EXIT_CODE = 199;

  public static void main(String[] args) throws IOException {
    System.exit(checkDeps(args));
  }

  @VisibleForTesting
  static int checkDeps(String[] args) throws IOException {
    Options options = parseCommandLineOptions(args);

    if (options.output != null && !Files.exists(options.output)) {
      Files.createFile(options.output); // Make sure the output file always exists.
    }

    int exitCode = 0;
    try (ImportDepsChecker checker =
        new ImportDepsChecker(
            ImmutableList.copyOf(options.bootclasspath),
            // Consider everything direct if no direct classpath is given
            options.directClasspath.isEmpty()
                ? ImmutableList.copyOf(options.fullClasspath)
                : ImmutableList.copyOf(options.directClasspath),
            ImmutableList.copyOf(options.fullClasspath),
            ImmutableList.copyOf(options.inputJars))) {
      if (!checker.check() && options.checkingMode != CheckingMode.SILENCE) {
        String result = checker.computeResultOutput(options.ruleLabel);
        checkState(!result.isEmpty(), "The result should NOT be empty.");
        exitCode = options.checkingMode == CheckingMode.ERROR ? DEPS_ERROR_EXIT_CODE : 0;
        printErrorMessage(result, options);
        if (options.output != null) {
          asCharSink(options.output, StandardCharsets.UTF_8).write(result);
        }
      }
      if (options.jdepsOutput != null) {
        Dependencies dependencies = checker.emitJdepsProto(options.ruleLabel);
        try (OutputStream os =
            new BufferedOutputStream(Files.newOutputStream(options.jdepsOutput))) {
          dependencies.writeTo(os);
        }
      }
    }
    return exitCode;
  }

  private static void printErrorMessage(String detailedErrorMessage, Options options) {
    checkArgument(
        options.checkingMode == CheckingMode.ERROR || options.checkingMode == CheckingMode.WARNING);
    System.err.print(options.checkingMode == CheckingMode.ERROR ? "ERROR" : "WARNING");
    System.err.printf(
        ": The dependencies for the following %d jar(s) are not complete.\n",
        options.inputJars.size());
    int index = 1;
    for (Path jar : options.inputJars) {
      System.err.printf("    %3d.%s\n", index++, jar.toString());
    }
    System.err.println("The details are listed below:");
    System.err.print(detailedErrorMessage);
  }

  @VisibleForTesting
  static Options parseCommandLineOptions(String[] args) throws IOException {
    OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class);
    optionsParser.setAllowResidue(false);
    optionsParser.enableParamsFileSupport(
        new ShellQuotedParamsFilePreProcessor(FileSystems.getDefault()));
    optionsParser.parseAndExitUponError(args);
    Options options = optionsParser.getOptions(Options.class);

    checkArgument(!options.inputJars.isEmpty(), "--input is required");
    checkArgument(!options.bootclasspath.isEmpty(), "--bootclasspath_entry is required");
    // TODO(cushon): make --jdeps_output mandatory
    // checkArgument(
    //     options.jdepsOutput != null, "Invalid value of --jdeps_output: '%s'",
    //     options.jdepsOutput);
    if (!options.fullClasspath.containsAll(options.directClasspath)) {
      ArrayList<Path> missing = Lists.newArrayList(options.directClasspath);
      missing.removeAll(options.fullClasspath);
      throw new IllegalArgumentException(
          "--strictdeps must be a subset of --classpath_entry but has additional entries: "
              + missing);
    }

    return options;
  }

  /** Validating converter for Paths. A Path is considered valid if it resolves to a file. */
  public static class PathConverter implements Converter<Path> {

    private final boolean mustExist;

    public PathConverter() {
      this.mustExist = false;
    }

    protected PathConverter(boolean mustExist) {
      this.mustExist = mustExist;
    }

    @Override
    public Path convert(String input) throws OptionsParsingException {
      try {
        Path path = FileSystems.getDefault().getPath(input);
        if (mustExist && !Files.exists(path)) {
          throw new OptionsParsingException(
              String.format("%s is not a valid path: it does not exist.", input));
        }
        return path;
      } catch (InvalidPathException e) {
        throw new OptionsParsingException(
            String.format("%s is not a valid path: %s.", input, e.getMessage()), e);
      }
    }

    @Override
    public String getTypeDescription() {
      return "a valid filesystem path";
    }
  }

  /**
   * Validating converter for Paths. A Path is considered valid if it resolves to a file and exists.
   */
  public static class ExistingPathConverter extends PathConverter {
    public ExistingPathConverter() {
      super(true);
    }
  }

  /** Converter for {@link CheckingMode} */
  public static class CheckingModeConverter extends EnumConverter<CheckingMode> {
    public CheckingModeConverter() {
      super(CheckingMode.class, "The checking mode for the dependency checker.");
    }
  }

  /**
   * The checking mode of the dependency checker.
   */
  public enum CheckingMode {
    /** Emit 'errors' on missing or incomplete dependencies. */
    ERROR,
    /** Emit 'warnings' on missing or incomplete dependencies. */
    WARNING,
    /**
     * Emit 'nothing' on missing or incomplete dependencies. This is mainly used to dump jdeps
     * protos.
     */
    SILENCE
  }
}
