/*
 * Copyright 2012-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.Project;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.parser.NoSuchBuildTargetException;
import com.facebook.buck.parser.PartialGraph;
import com.facebook.buck.parser.RawRulePredicate;
import com.facebook.buck.rules.BuildRuleType;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.util.HumanReadableException;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.io.Files;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;
import java.util.Map;

public class ProjectCommand extends AbstractCommandRunner<ProjectCommandOptions> {

  /**
   * Predicate used to filter out all PROJECT_CONFIG rules in the dependency graph.
   */
  private static final RawRulePredicate predicate = new RawRulePredicate() {
    @Override
    public boolean isMatch(Map<String, Object> rawParseData,
        BuildRuleType buildRuleType,
        BuildTarget buildTarget) {
      return buildRuleType == BuildRuleType.PROJECT_CONFIG;
    }
  };


  public ProjectCommand() {}

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

  @Override
  int runCommandWithOptions(ProjectCommandOptions options) throws IOException {
    // Create a PartialGraph that only contains targets that can be represented as IDE
    // configuration files.
    PartialGraph partialGraph;

    try {
      partialGraph = createPartialGraph(predicate, options);
    } catch (NoSuchBuildTargetException e) {
      throw new HumanReadableException(e);
    }

    ExecutionContext executionContext = new ExecutionContext(
        options.getVerbosity(),
        getProjectFilesystem().getProjectRoot(),
        options.findAndroidPlatformTarget(partialGraph.getDependencyGraph(), stdErr),
        options.findAndroidNdkDir(),
        ansi,
        false /* isCodeCoverageEnabled */,
        false /* isDebugEnabled */,
        stdOut,
        stdErr);

    Project project = new Project(partialGraph,
        options.getBasePathToAliasMap(),
        options.getJavaPackageFinder(),
        executionContext,
        getProjectFilesystem(),
        options.getPathToDefaultAndroidManifest());

    File tempFile = new File(Files.createTempDir(), "project.json");
    int exitCode;
    try {
      exitCode = createIntellijProject(project, tempFile, console.getStdOut());
      if (exitCode != 0) {
        return exitCode;
      }

      List<String> additionalInitialTargets = ImmutableList.of();

      // Build initial targets.
      if (options.hasInitialTargets() || !additionalInitialTargets.isEmpty()) {
        BuildCommand buildCommand = new BuildCommand(stdOut, stdErr, console, getProjectFilesystem());

        exitCode = runBuildCommand(
            buildCommand,
            options.createBuildCommandOptionsWithInitialTargets(additionalInitialTargets));

        if (exitCode != 0) {
          return exitCode;
        }
      }
    } finally {
      // Either leave project.json around for debugging or delete it on exit.
      if (options.getVerbosity().shouldPrintOutput()) {
        stdErr.printf("project.json was written to %s", tempFile.getAbsolutePath());
      } else {
        tempFile.deleteOnExit();
      }
    }

    return 0;
  }


  /**
   * Calls {@link Project#createIntellijProject}
   *
   * This is factored into a separate method for testing purposes.
   */
  @VisibleForTesting
  int createIntellijProject(Project project, File jsonTemplate, PrintStream stdOut)
      throws IOException {
    return project.createIntellijProject(jsonTemplate, stdOut);
  }

  /**
   * Calls {@link BuildCommand#runCommandWithOptions}
   *
   * This is factored into a separate method for testing purposes.
   */
  @VisibleForTesting
  int runBuildCommand(BuildCommand buildCommand, BuildCommandOptions options)
      throws IOException {
    return buildCommand.runCommandWithOptions(options);
  }

  @VisibleForTesting
  PartialGraph createPartialGraph(RawRulePredicate rulePredicate, ProjectCommandOptions options)
      throws IOException, NoSuchBuildTargetException {
    return PartialGraph.createPartialGraph(
        rulePredicate,
        getProjectFilesystem().getProjectRoot(),
        options.getDefaultIncludes());
  }

  @Override
  String getUsageIntro() {
    return "generates project configuration files for an IDE";
  }

}
