/*
 * 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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.facebook.buck.event.BuckEventBus;
import com.facebook.buck.event.BuckEventBusFactory;
import com.facebook.buck.graph.MutableDirectedGraph;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.model.BuildTargetPattern;
import com.facebook.buck.rules.ArtifactCache;
import com.facebook.buck.rules.BuildContext;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleSuccess;
import com.facebook.buck.rules.BuildRuleType;
import com.facebook.buck.rules.Buildable;
import com.facebook.buck.rules.BuildableProperties;
import com.facebook.buck.rules.DependencyGraph;
import com.facebook.buck.rules.KnownBuildRuleTypes;
import com.facebook.buck.rules.NoopArtifactCache;
import com.facebook.buck.rules.RuleKey;
import com.facebook.buck.testutil.TestConsole;
import com.facebook.buck.util.Console;
import com.facebook.buck.util.MorePaths;
import com.facebook.buck.util.ProjectFilesystem;
import com.facebook.buck.util.environment.Platform;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.util.concurrent.ListenableFuture;

import org.junit.Before;
import org.junit.Test;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;

import java.io.File;
import java.nio.file.Path;
import java.util.Arrays;

import javax.annotation.Nullable;

/**
 * Outputs targets that own a specified list of files.
 */
public class AuditOwnerCommandTest {

  private static class StubBuildRule implements BuildRule {

    private final ImmutableSet<Path> inputs;
    private final BuildTarget target;

    public StubBuildRule(BuildTarget target, Iterable<Path> inputs) {
      this.target = target;
      this.inputs = ImmutableSet.copyOf(inputs);
    }

    @Override
    public Iterable<Path> getInputs() {
      return inputs;
    }

    @Override
    public BuildTarget getBuildTarget() {
      return target;
    }

    @Override
    public String getFullyQualifiedName() {
      return target.getFullyQualifiedName();
    }

    @Override
    public BuildRuleType getType() {
      throw new UnsupportedOperationException();
    }

    @Nullable
    @Override
    public Buildable getBuildable() {
      return null;
    }

    @Override
    public BuildableProperties getProperties() {
      throw new UnsupportedOperationException();
    }

    @Override
    public ImmutableSortedSet<BuildRule> getDeps() {
      throw new UnsupportedOperationException();
    }

    @Override
    public ImmutableSet<BuildTargetPattern> getVisibilityPatterns() {
      throw new UnsupportedOperationException();
    }

    @Override
    public boolean isVisibleTo(BuildTarget target) {
      throw new UnsupportedOperationException();
    }

    @Override
    public ListenableFuture<BuildRuleSuccess> build(BuildContext context) {
      throw new UnsupportedOperationException();
    }

    @Override
    public BuildRuleSuccess.Type getBuildResultType() {
      throw new UnsupportedOperationException();
    }

    @Override
    public boolean getExportDeps() {
      throw new UnsupportedOperationException();
    }

    @Override
    public final RuleKey getRuleKey() {
      throw new UnsupportedOperationException();
    }

    @Override
    public final RuleKey getRuleKeyWithoutDeps() {
      throw new UnsupportedOperationException();
    }

    @Override
    public int compareTo(BuildRule buildRule) {
      return this.getFullyQualifiedName().compareTo(buildRule.getFullyQualifiedName());
    }
  }

  private static class FakeProjectFilesystem extends ProjectFilesystem {
    public FakeProjectFilesystem() {
      super(new File("."));
    }
  }

  @SuppressWarnings("serial")
  private static class ExistingDirectoryFile extends File {
    public ExistingDirectoryFile(File file, String s) {
      super(file, s);
    }

    @Override
    public boolean isFile() {
      return false;
    }

    @Override
    public boolean isDirectory() {
      return true;
    }

    @Override
    public boolean exists() {
      return true;
    }
  }

  @SuppressWarnings("serial")
  private static class MissingFile extends File {
    public MissingFile(File file, String s) {
      super(file, s);
    }

    @Override
    public boolean exists() {
      return false;
    }

    @Override
    public boolean isFile() {
      return true;
    }

    @Override
    public boolean isDirectory() {
      return false;
    }
  }

  @SuppressWarnings("serial")
  private static class ExistingFile extends File {
    public ExistingFile(File file, String s) {
      super(file, s);
    }

    @Override
    public boolean exists() {
      return true;
    }

    @Override
    public boolean isFile() {
      return true;
    }

    @Override
    public boolean isDirectory() {
      return false;
    }
  }

  private BuckConfig buckConfig;

  @Before
  public void setUp() {
    buckConfig = new FakeBuckConfig();
  }

  private AuditOwnerOptions getOptions(String... args) throws CmdLineException {
    AuditOwnerOptions options = new AuditOwnerOptions(buckConfig);
    new CmdLineParser(options).parseArgument(args);
    return options;
  }

  private AuditOwnerCommand createAuditOwnerCommand(ProjectFilesystem filesystem) {
    Console console = new TestConsole();
    KnownBuildRuleTypes buildRuleTypes = new KnownBuildRuleTypes();
    ArtifactCache artifactCache = new NoopArtifactCache();
    BuckEventBus eventBus = BuckEventBusFactory.newInstance();
    return new AuditOwnerCommand(new CommandRunnerParams(
        console,
        filesystem,
        buildRuleTypes,
        new InstanceArtifactCacheFactory(artifactCache),
        eventBus,
        buckConfig.getPythonInterpreter(),
        Platform.detect()));
  }

  @Test
  public void verifyPathsThatAreNotFilesAreCorrectlyReported() throws CmdLineException {
    // All files will be directories now
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem() {
      @Override
      public File getFileForRelativePath(String pathRelativeToProjectRoot) {
        return new ExistingDirectoryFile(getProjectRoot(), pathRelativeToProjectRoot);
      }
    };

    // Empty graph
    MutableDirectedGraph<BuildRule> mutableGraph = new MutableDirectedGraph<BuildRule>();
    DependencyGraph graph = new DependencyGraph(mutableGraph);

    // Inputs that should be treated as "non-files", i.e. as directories
    String[] args = new String[] {
        "java/somefolder/badfolder",
        "java/somefolder",
        "com/test/subtest"
    };
    ImmutableSet<String> inputs = ImmutableSet.copyOf(args);

    // Create options
    AuditOwnerOptions options = getOptions(args);

    // Create command under test
    AuditOwnerCommand command = createAuditOwnerCommand(filesystem);

    // Generate report and verify nonFileInputs are filled in as expected.
    AuditOwnerCommand.OwnersReport report = command.generateOwnersReport(graph, options);
    assertTrue(report.owners.isEmpty());
    assertTrue(report.nonExistentInputs.isEmpty());
    assertTrue(report.inputsWithNoOwners.isEmpty());
    assertEquals(inputs, report.nonFileInputs);
  }

  @Test
  public void verifyMissingFilesAreCorrectlyReported() throws CmdLineException {
    // All files will be directories now
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem() {
      @Override
      public File getFileForRelativePath(String pathRelativeToProjectRoot) {
        return new MissingFile(getProjectRoot(), pathRelativeToProjectRoot);
      }
    };

    // Empty graph
    MutableDirectedGraph<BuildRule> mutableGraph = new MutableDirectedGraph<BuildRule>();
    DependencyGraph graph = new DependencyGraph(mutableGraph);

    // Inputs that should be treated as missing files
    String[] args = new String[] {
        "java/somefolder/badfolder/somefile.java",
        "java/somefolder/perfect.java",
        "com/test/subtest/random.java"
    };
    ImmutableSet<String> inputs = ImmutableSet.copyOf(args);

    // Create options
    AuditOwnerOptions options = getOptions(args);

    // Create command under test
    AuditOwnerCommand command = createAuditOwnerCommand(filesystem);

    // Generate report and verify nonFileInputs are filled in as expected.
    AuditOwnerCommand.OwnersReport report = command.generateOwnersReport(graph, options);
    assertTrue(report.owners.isEmpty());
    assertTrue(report.nonFileInputs.isEmpty());
    assertTrue(report.inputsWithNoOwners.isEmpty());
    assertEquals(inputs, report.nonExistentInputs);
  }

  @Test
  public void verifyInputsWithoutOwnersAreCorrectlyReported() throws CmdLineException {
    // All files will be directories now
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem() {
      @Override
      public File getFileForRelativePath(String pathRelativeToProjectRoot) {
        return new ExistingFile(getProjectRoot(), pathRelativeToProjectRoot);
      }
    };

    // Empty graph
    MutableDirectedGraph<BuildRule> mutableGraph = new MutableDirectedGraph<BuildRule>();
    DependencyGraph graph = new DependencyGraph(mutableGraph);

    // Inputs that should be treated as existing files
    String[] args = new String[] {
        "java/somefolder/badfolder/somefile.java",
        "java/somefolder/perfect.java",
        "com/test/subtest/random.java"
    };
    ImmutableSortedSet<Path> inputs = MorePaths.asPaths(Arrays.asList(args));

    // Create options
    AuditOwnerOptions options = getOptions(args);

    // Create command under test
    AuditOwnerCommand command = createAuditOwnerCommand(filesystem);

    // Generate report and verify nonFileInputs are filled in as expected.
    AuditOwnerCommand.OwnersReport report = command.generateOwnersReport(graph, options);
    assertTrue(report.owners.isEmpty());
    assertTrue(report.nonFileInputs.isEmpty());
    assertTrue(report.nonExistentInputs.isEmpty());
    assertEquals(inputs, report.inputsWithNoOwners);
  }

  /**
   * Verify that owners are correctly detected:
   *  - one owner, multiple inputs
   */
  @Test
  public void verifyInputsWithOneOwnerAreCorrectlyReported() throws CmdLineException {
    // All files will be directories now
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem() {
      @Override
      public File getFileForRelativePath(String pathRelativeToProjectRoot) {
        return new ExistingFile(getProjectRoot(), pathRelativeToProjectRoot);
      }
    };

    // Create inputs
    String[] args = new String[] {
        "java/somefolder/badfolder/somefile.java",
        "java/somefolder/perfect.java",
        "com/test/subtest/random.java"
    };
    ImmutableSortedSet<Path> inputs = MorePaths.asPaths(ImmutableSortedSet.copyOf(args));

    // Build rule that owns all inputs
    BuildTarget target = new BuildTarget("//base/name", "name");
    BuildRule ownerRule = new StubBuildRule(target, inputs);

    // Create graph
    MutableDirectedGraph<BuildRule> mutableGraph = new MutableDirectedGraph<BuildRule>();
    mutableGraph.addNode(ownerRule);

    DependencyGraph graph = new DependencyGraph(mutableGraph);

    // Create options
    AuditOwnerOptions options = getOptions(args);

    // Create command under test
    AuditOwnerCommand command = createAuditOwnerCommand(filesystem);

    // Generate report and verify nonFileInputs are filled in as expected.
    AuditOwnerCommand.OwnersReport report = command.generateOwnersReport(graph, options);
    assertTrue(report.nonFileInputs.isEmpty());
    assertTrue(report.nonExistentInputs.isEmpty());
    assertTrue(report.inputsWithNoOwners.isEmpty());

    assertEquals(inputs.size(), report.owners.size());
    assertTrue(report.owners.containsKey(ownerRule));
    assertEquals(ownerRule.getInputs(), report.owners.get(ownerRule));
  }

  /**
   * Verify that owners are correctly detected:
   *  - inputs that belong to multiple targets
   */
  @Test
  public void verifyInputsWithMultipleOwnersAreCorrectlyReported() throws CmdLineException {
    // All files will be directories now
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem() {
      @Override
      public File getFileForRelativePath(String pathRelativeToProjectRoot) {
        return new ExistingFile(getProjectRoot(), pathRelativeToProjectRoot);
      }
    };

    // Create inputs
    String[] args = new String[] {
        "java/somefolder/badfolder/somefile.java",
        "java/somefolder/perfect.java",
        "com/test/subtest/random.java"
    };
    ImmutableSortedSet<Path> inputs = MorePaths.asPaths(ImmutableSortedSet.copyOf(args));

    // Build rule that owns all inputs
    BuildTarget target1 = BuildTargetFactory.newInstance("//base/name1:name1");
    BuildTarget target2 = BuildTargetFactory.newInstance("//base/name2:name2");
    BuildRule owner1Rule = new StubBuildRule(target1, inputs);
    BuildRule owner2Rule = new StubBuildRule(target2, inputs);

    // Create graph
    MutableDirectedGraph<BuildRule> mutableGraph = new MutableDirectedGraph<BuildRule>();
    mutableGraph.addNode(owner1Rule);
    mutableGraph.addNode(owner2Rule);

    DependencyGraph graph = new DependencyGraph(mutableGraph);

    // Create options
    AuditOwnerOptions options = getOptions(args);

    // Create command under test
    AuditOwnerCommand command = createAuditOwnerCommand(filesystem);

    // Generate report and verify nonFileInputs are filled in as expected.
    AuditOwnerCommand.OwnersReport report = command.generateOwnersReport(graph, options);
    assertTrue(report.nonFileInputs.isEmpty());
    assertTrue(report.nonExistentInputs.isEmpty());
    assertTrue(report.inputsWithNoOwners.isEmpty());

    assertTrue(report.owners.containsKey(owner1Rule));
    assertTrue(report.owners.containsKey(owner2Rule));
    assertEquals(owner1Rule.getInputs(), report.owners.get(owner1Rule));
    assertEquals(owner2Rule.getInputs(), report.owners.get(owner2Rule));
  }

}
