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

import static com.facebook.buck.util.BuckConstant.GEN_DIR;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.facebook.buck.event.BuckEventBusFactory;
import com.facebook.buck.java.DefaultJavaLibraryRule;
import com.facebook.buck.java.Keystore;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.model.BuildTargetPattern;
import com.facebook.buck.parser.BuildRuleFactoryParams;
import com.facebook.buck.parser.BuildTargetParser;
import com.facebook.buck.parser.NoSuchBuildTargetException;
import com.facebook.buck.parser.NonCheckingBuildRuleFactoryParams;
import com.facebook.buck.parser.ParseContext;
import com.facebook.buck.rules.ArtifactCache;
import com.facebook.buck.rules.BuildContext;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.BuildRuleType;
import com.facebook.buck.rules.DependencyGraph;
import com.facebook.buck.rules.FakeAbstractBuildRuleBuilderParams;
import com.facebook.buck.rules.FakeBuildableContext;
import com.facebook.buck.rules.JavaPackageFinder;
import com.facebook.buck.shell.ShellStep;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.Step;
import com.facebook.buck.step.StepRunner;
import com.facebook.buck.step.fs.MakeCleanDirectoryStep;
import com.facebook.buck.step.fs.MkdirAndSymlinkFileStep;
import com.facebook.buck.step.fs.MkdirStep;
import com.facebook.buck.step.fs.RmStep;
import com.facebook.buck.testutil.TestConsole;
import com.facebook.buck.util.ProjectFilesystem;
import com.facebook.buck.util.environment.Platform;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;

import org.easymock.EasyMock;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;

/**
 * Unit test for {@link com.facebook.buck.android.ApkGenrule}.
 */
public class ApkGenruleTest {

  private static final Function<String, String> relativeToAbsolutePathFunction =
      new Function<String, String>() {
        @Override
        public String apply(String path) {
          return String.format("/opt/local/fbandroid/%s", path);
        }
      };

  private void createSampleAndroidBinaryRule(BuildRuleResolver ruleResolver) {
    // Create a java_binary that depends on a java_library so it is possible to create a
    // java_binary rule with a classpath entry and a main class.
    BuildTarget libAndroidTarget = BuildTargetFactory.newInstance("//:lib-android");
    ruleResolver.buildAndAddToIndex(
        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(libAndroidTarget)
        .addSrc("java/com/facebook/util/Facebook.java"));

    BuildTarget keystoreTarget = BuildTargetFactory.newInstance("//keystore:debug");
    ruleResolver.buildAndAddToIndex(
        Keystore.newKeystoreBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(keystoreTarget)
        .setStore("keystore/debug.keystore")
        .setProperties("keystore/debug.keystore.properties")
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));

    ruleResolver.buildAndAddToIndex(
        AndroidBinaryRule.newAndroidBinaryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
        .setBuildTarget(BuildTargetFactory.newInstance("//:fb4a"))
        .setManifest("AndroidManifest.xml")
        .setTarget("Google Inc.:Google APIs:16")
        .setKeystore(keystoreTarget)
        .addDep(libAndroidTarget)
        .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));
  }

  @Test
  @SuppressWarnings("PMD.AvoidUsingHardCodedIP")
  public void testCreateAndRunApkGenrule() throws IOException, NoSuchBuildTargetException {
    BuildRuleResolver ruleResolver = new BuildRuleResolver();
    createSampleAndroidBinaryRule(ruleResolver);
    Map<String, ?> instance = new ImmutableMap.Builder<String, Object>()
        .put("name", "fb4a_signed")
        .put("srcs", ImmutableList.<String>of("signer.py", "key.properties"))
        .put("cmd", "python signer.py $APK key.properties > $OUT")
        .put("apk", ":fb4a")
        .put("out", "signed_fb4a.apk")
        .put("deps", ImmutableList.<Object>of())
        .build();

    // From the Python object, create a ApkGenruleBuildRuleFactory to create a ApkGenrule.Builder
    // that builds a ApkGenrule from the Python object.
    BuildTargetParser parser = EasyMock.createNiceMock(BuildTargetParser.class);
    EasyMock.expect(parser.parse(EasyMock.eq(":fb4a"), EasyMock.anyObject(ParseContext.class)))
        .andStubReturn(BuildTargetFactory.newInstance("//:fb4a"));
    EasyMock.replay(parser);

    BuildTarget buildTarget = new BuildTarget("//src/com/facebook", "sign_fb4a");
    BuildRuleFactoryParams params = NonCheckingBuildRuleFactoryParams.
        createNonCheckingBuildRuleFactoryParams(
            instance,
            parser,
            buildTarget);

    ApkGenruleBuildRuleFactory factory = new ApkGenruleBuildRuleFactory();
    ApkGenrule.Builder builder = factory.newInstance(params);
    builder.setRelativeToAbsolutePathFunctionForTesting(relativeToAbsolutePathFunction);
    ApkGenrule apkGenrule = (ApkGenrule) ruleResolver.buildAndAddToIndex(builder);

    // Verify all of the observers of the Genrule.
    String expectedApkOutput = "/opt/local/fbandroid/" + GEN_DIR + "/src/com/facebook/sign_fb4a.apk";
    assertEquals(BuildRuleType.APK_GENRULE, apkGenrule.getType());
    assertEquals(expectedApkOutput,
        apkGenrule.getAbsoluteOutputFilePath());
    BuildContext buildContext = BuildContext.builder()
        .setDependencyGraph(EasyMock.createMock(DependencyGraph.class))
        .setStepRunner(EasyMock.createNiceMock(StepRunner.class))
        .setProjectFilesystem(EasyMock.createNiceMock(ProjectFilesystem.class))
        .setArtifactCache(EasyMock.createMock(ArtifactCache.class))
        .setJavaPackageFinder(EasyMock.createNiceMock(JavaPackageFinder.class))
        .setEventBus(BuckEventBusFactory.newInstance())
        .build();
    ImmutableSortedSet<String> inputsToCompareToOutputs = ImmutableSortedSet.of(
        "src/com/facebook/key.properties",
        "src/com/facebook/signer.py");
    assertEquals(inputsToCompareToOutputs,
        apkGenrule.getInputsToCompareToOutput());

    // Verify that the shell commands that the genrule produces are correct.
    List<Step> steps = apkGenrule.getBuildSteps(buildContext, new FakeBuildableContext());
    assertEquals(7, steps.size());

    Step firstStep = steps.get(0);
    assertTrue(firstStep instanceof RmStep);
    RmStep rmCommand = (RmStep) firstStep;
    ExecutionContext executionContext = newEmptyExecutionContext();
    assertEquals(
        "First command should delete the output file to be written by the genrule.",
        ImmutableList.of(
            "rm",
            "-f",
            apkGenrule.getPathToOutputFile()),
        rmCommand.getShellCommand(executionContext));

    Step secondStep = steps.get(1);
    assertTrue(secondStep instanceof MkdirStep);
    MkdirStep mkdirCommand = (MkdirStep) secondStep;
    assertEquals(
        "Second command should make sure the output directory exists.",
        Paths.get(GEN_DIR + "/src/com/facebook/"),
        mkdirCommand.getPath(executionContext));

    Step thirdStep = steps.get(2);
    assertTrue(thirdStep instanceof MakeCleanDirectoryStep);
    MakeCleanDirectoryStep secondMkdirCommand = (MakeCleanDirectoryStep) thirdStep;
    String relativePathToTmpDir = GEN_DIR + "/src/com/facebook/sign_fb4a__tmp";
    assertEquals(
        "Third command should make sure the temp directory exists.",
        relativePathToTmpDir,
        secondMkdirCommand.getPath());

    Step fourthStep = steps.get(3);
    assertTrue(fourthStep instanceof MakeCleanDirectoryStep);
    MakeCleanDirectoryStep thirdMkdirCommand = (MakeCleanDirectoryStep) fourthStep;
    String relativePathToSrcDir = GEN_DIR + "/src/com/facebook/sign_fb4a__srcs";
    assertEquals(
        "Fourth command should make sure the temp directory exists.",
        relativePathToSrcDir,
        thirdMkdirCommand.getPath());

    MkdirAndSymlinkFileStep linkSource1 = (MkdirAndSymlinkFileStep) steps.get(4);
    assertEquals("src/com/facebook/signer.py", linkSource1.getSource());
    assertEquals(relativePathToSrcDir + "/signer.py", linkSource1.getTarget());

    MkdirAndSymlinkFileStep linkSource2 = (MkdirAndSymlinkFileStep) steps.get(5);
    assertEquals("src/com/facebook/key.properties", linkSource2.getSource());
    assertEquals(relativePathToSrcDir + "/key.properties", linkSource2.getTarget());

    Step seventhStep = steps.get(6);
    assertTrue(seventhStep instanceof ShellStep);
    ShellStep genruleCommand = (ShellStep) seventhStep;
    assertEquals("genrule", genruleCommand.getShortName());
    assertEquals(new ImmutableMap.Builder<String, String>()
        .put("SRCS", "/opt/local/fbandroid/src/com/facebook/signer.py " +
            "/opt/local/fbandroid/src/com/facebook/key.properties")
        .put("APK", GEN_DIR + "/fb4a.apk")
        .put("GEN_DIR", "/opt/local/fbandroid/" + GEN_DIR)
        .put("DEPS", "")
        .put("TMP", "/opt/local/fbandroid/" + relativePathToTmpDir)
        .put("SRCDIR", "/opt/local/fbandroid/" + relativePathToSrcDir)
        .put("OUT", expectedApkOutput).build(),
        genruleCommand.getEnvironmentVariables(executionContext));
    assertEquals(
        ImmutableList.of("/bin/bash", "-e", "-c", "python signer.py $APK key.properties > $OUT"),
        genruleCommand.getShellCommand(executionContext));

    EasyMock.verify(parser);
  }

  private ExecutionContext newEmptyExecutionContext() {
    return ExecutionContext.builder()
        .setConsole(new TestConsole())
        .setProjectFilesystem(new ProjectFilesystem(new File(".")) {
          @Override
          public Function<String, String> getPathRelativizer() {
            return Functions.identity();
          }

          @Override
          public Path resolve(Path path) {
            return path;
          }
        })
        .setEventBus(BuckEventBusFactory.newInstance())
        .setPlatform(Platform.LINUX) // Fix platform to Linux to use bash in genrule.
        .build();
  }
}
