/*
 * 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.json.BuildFileParseException;
import com.facebook.buck.json.ProjectBuildFileParser;
import com.facebook.buck.util.Escaper;
import com.facebook.buck.util.HumanReadableException;
import com.facebook.buck.util.MoreStrings;
import com.facebook.buck.util.ProjectFilesystem;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;

import javax.annotation.Nullable;

/**
 * Evaluates a build file and prints out an equivalent build file with all includes/macros
 * expanded. When complex macros are in play, this helps clarify what the resulting build rule
 * definitions are.
 */
public class AuditRulesCommand extends AbstractCommandRunner<AuditRulesOptions> {

  /** Indent to use in generated build file. */
  private static String INDENT = "  ";

  /**
   * Properties from the JSON produced by {@code buck.py} that start with this prefix do not
   * correspond to build rule arguments specified by the user. Instead, they contain internal-only
   * metadata, so they should not be printed when the build rule is reproduced.
   */
  private static final String INTERNAL_PROPERTY_NAME_PREFIX = "buck.";

  /**
   * The name of the property in the JSON produced by {@code buck.py} that identifies the type of
   * the build rule being defined.
   * <p>
   * TODO(mbolin): Change this property name to "buck.type" so that all internal properties start
   * with "buck.".
   */
  private static final String TYPE_PROPERTY_NAME = "type";

  /** Properties that should be listed last in the declaration of a build rule. */
  private static final ImmutableSet<String> LAST_PROPERTIES = ImmutableSet.of("deps", "visibility");

  protected AuditRulesCommand(CommandRunnerParams params) {
    super(params);
  }

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

  @Override
  String getUsageIntro() {
    return "List build rule definitions resulting from expanding macros.";
  }

  /** Prints the expanded build rules from the specified build files to the console. */
  @Override
  int runCommandWithOptionsInternal(AuditRulesOptions options) throws IOException {
    ProjectFilesystem projectFilesystem = getProjectFilesystem();
    ProjectBuildFileParser parser = new ProjectBuildFileParser(projectFilesystem,
        options.getBuckConfig().getDefaultIncludes(),
        options.getBuckConfig().getPythonInterpreter());
    PrintStream out = console.getStdOut();
    for (String pathToBuildFile : options.getArguments()) {
      // Print a comment with the path to the build file.
      out.printf("# %s\n\n", pathToBuildFile);

      // Resolve the path specified by the user.
      Path path = Paths.get(pathToBuildFile);
      if (!path.isAbsolute()) {
        Path root = projectFilesystem.getRootPath();
        path = root.resolve(path);
      }

      // Parse the rules from the build file.
      List<Map<String, Object>> rawRules;
      try {
        rawRules = parser.getAllRules(path.toString());
      } catch (BuildFileParseException e) {
        throw new HumanReadableException(e);
      }

      // Format and print the rules from the raw data, filtered by type.
      final ImmutableSet<String> types = options.getTypes();
      Predicate<String> includeType = new Predicate<String>() {
          @Override
          public boolean apply(String type) {
            return types.isEmpty() || types.contains(type);
          }};
      printRulesToStdout(rawRules, includeType);
    }

    return 0;
  }

  private void printRulesToStdout(List<Map<String, Object>> rawRules,
      Predicate<String> includeType) {
    PrintStream out = console.getStdOut();

    for (Map<String, Object> rawRule : rawRules) {
      String type = (String)rawRule.get(TYPE_PROPERTY_NAME);
      if (!includeType.apply(type)) {
        continue;
      }

      out.printf("%s(\n", type);

      // The properties in the order they should be displayed for this rule.
      LinkedHashSet<String> properties = Sets.newLinkedHashSet();

      // Always display the "name" property first.
      properties.add("name");

      // Add the properties specific to the rule.
      SortedSet<String> customProperties = Sets.newTreeSet();
      for (String key : rawRule.keySet()) {
        // Ignore keys that start with "buck.".
        if (!(key.equals(TYPE_PROPERTY_NAME) ||
            key.startsWith(INTERNAL_PROPERTY_NAME_PREFIX) ||
            LAST_PROPERTIES.contains(key))) {
          customProperties.add(key);
        }
      }
      properties.addAll(customProperties);

      // Add common properties that should be displayed last.
      properties.addAll(LAST_PROPERTIES);

      // Write out the properties and their corresponding values.
      for (String property : properties) {
        String displayValue = createDisplayString(rawRule.get(property));
        out.printf("%s%s = %s,\n", INDENT, property, displayValue);
      }

      // Close the rule definition.
      out.printf(")\n\n");
    }
  }

  /**
   * @param value in a Map returned by {@link ProjectBuildFileParser#getAllRules(String)}.
   * @return a string that represents the Python equivalent of the value.
   */
  @VisibleForTesting
  static String createDisplayString(@Nullable Object value) {
    if (value == null) {
      return "None";
    } else if (value instanceof Boolean) {
      return MoreStrings.capitalize(value.toString());
    } else if (value instanceof String) {
      return Escaper.escapeAsPythonString(value.toString());
    } else if (value instanceof Number) {
      return value.toString();
    } else if (value instanceof List) {
      StringBuilder out = new StringBuilder("[\n");

      String indent = Strings.repeat(INDENT, 2);
      for (Object item : (List<?>)value) {
        out.append(indent).append(createDisplayString(item)).append(",\n");
      }

      out.append(INDENT).append("]");
      return out.toString();
    } else {
      throw new IllegalStateException();
    }
  }
}
