/*
 * Copyright 2014-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 com.facebook.buck.cxx.CxxPlatform;
import com.facebook.buck.cxx.CxxPreprocessables;
import com.facebook.buck.cxx.CxxPreprocessorDep;
import com.facebook.buck.cxx.CxxPreprocessorInput;
import com.facebook.buck.cxx.CxxSource;
import com.facebook.buck.cxx.Linker;
import com.facebook.buck.cxx.NativeLinkable;
import com.facebook.buck.cxx.NativeLinkableInput;
import com.facebook.buck.cxx.NativeLinkables;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargets;
import com.facebook.buck.model.Flavor;
import com.facebook.buck.model.ImmutableFlavor;
import com.facebook.buck.rules.AbstractBuildRule;
import com.facebook.buck.rules.BuildContext;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.BuildRuleType;
import com.facebook.buck.rules.BuildableContext;
import com.facebook.buck.rules.Description;
import com.facebook.buck.rules.ImmutableBuildRuleType;
import com.facebook.buck.rules.PathSourcePath;
import com.facebook.buck.rules.RuleKey;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.step.Step;
import com.facebook.buck.step.fs.MkdirStep;
import com.facebook.buck.step.fs.WriteFileStep;
import com.facebook.buck.util.BuckConstant;
import com.facebook.buck.util.Escaper;
import com.facebook.buck.util.MoreIterables;
import com.facebook.buck.util.MoreStrings;
import com.facebook.infer.annotation.SuppressFieldNotInitialized;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Functions;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicates;
import com.google.common.base.Suppliers;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;

import java.io.IOException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.EnumSet;
import java.util.Map;
import java.util.regex.Pattern;

public class NdkLibraryDescription implements Description<NdkLibraryDescription.Arg> {

  public static final BuildRuleType TYPE = ImmutableBuildRuleType.of("ndk_library");

  private static final BuildRuleType MAKEFILE_TYPE =
      ImmutableBuildRuleType.of("ndk_library_makefile");
  private static final Flavor MAKEFILE_FLAVOR = ImmutableFlavor.of("makefile");

  private static final Pattern EXTENSIONS_REGEX =
      Pattern.compile(
              ".*\\." +
              MoreStrings.regexPatternForAny("mk", "h", "hpp", "c", "cpp", "cc", "cxx") + "$");

  private final Optional<String> ndkVersion;
  private final ImmutableMap<AndroidBinary.TargetCpuType, NdkCxxPlatform> cxxPlatforms;

  public NdkLibraryDescription(
      Optional<String> ndkVersion,
      ImmutableMap<AndroidBinary.TargetCpuType, NdkCxxPlatform> cxxPlatforms) {
    this.ndkVersion = ndkVersion;
    this.cxxPlatforms = Preconditions.checkNotNull(cxxPlatforms);
  }

  @Override
  public BuildRuleType getBuildRuleType() {
    return TYPE;
  }

  @Override
  public Arg createUnpopulatedConstructorArg() {
    return new Arg();
  }

  private Iterable<String> escapeForMakefile(Iterable<String> args) {
    ImmutableList.Builder<String> escapedArgs = ImmutableList.builder();

    for (String arg : args) {
      String escapedArg = arg;

      // The ndk-build makefiles make heavy use of the "eval" function to propagate variables,
      // which means we need to perform additional makefile escaping for *every* "eval" that
      // gets used.  Turns out there are three "evals", so we escape a total of four times
      // including the initial escaping.  Since the makefiles eventually hand-off these values
      // to the shell, we first perform bash escaping.
      //
      escapedArg = Escaper.escapeAsBashString(escapedArg);
      for (int i = 0; i < 4; i++) {
        escapedArg = Escaper.escapeAsMakefileValueString(escapedArg);
      }

      // We run ndk-build from the root of the NDK, so fixup paths that use the relative path to
      // the buck out directory.
      if (arg.startsWith(BuckConstant.BUCK_OUTPUT_DIRECTORY)) {
        escapedArg = "$(BUCK_PROJECT_DIR)/" + escapedArg;
      }

      escapedArgs.add(escapedArg);
    }

    return escapedArgs.build();
  }

  private String getTargetArchAbi(AndroidBinary.TargetCpuType cpuType) {
    switch (cpuType) {
      case ARM:
        return "armeabi";
      case ARMV7:
        return "armeabi-v7a";
      case X86:
        return "x86";
      case MIPS:
        return "mips";
      default:
        throw new IllegalStateException();
    }
  }

  @VisibleForTesting
  protected static Path getGeneratedMakefilePath(BuildTarget target) {
    return BuildTargets.getGenPath(target, "Android.%s.mk");
  }

  /**
   * @return a {@link BuildRule} which generates a Android.mk which pulls in the local Android.mk
   *     file and also appends relevant preprocessor and linker flags to use C/C++ library deps.
   */
  private BuildRule generateMakefile(
      final BuildRuleParams params,
      BuildRuleResolver resolver) {

    SourcePathResolver pathResolver = new SourcePathResolver(resolver);

    ImmutableList.Builder<String> outputLinesBuilder = ImmutableList.builder();
    ImmutableSortedSet.Builder<BuildRule> deps = ImmutableSortedSet.naturalOrder();

    for (Map.Entry<AndroidBinary.TargetCpuType, NdkCxxPlatform> entry : cxxPlatforms.entrySet()) {
      CxxPlatform cxxPlatform = entry.getValue().getCxxPlatform();

      CxxPreprocessorInput cxxPreprocessorInput;
      try {
        // Collect the preprocessor input for all C/C++ library deps.  We search *through* other
        // NDK library rules.
        cxxPreprocessorInput =
            CxxPreprocessables.getTransitiveCxxPreprocessorInput(
                cxxPlatform,
                params.getDeps(),
                Predicates.or(
                    Predicates.instanceOf(CxxPreprocessorDep.class),
                    Predicates.instanceOf(NdkLibrary.class)));
      } catch (CxxPreprocessorInput.ConflictingHeadersException e) {
        throw e.getHumanReadableExceptionForBuildTarget(params.getBuildTarget());
      }

      // We add any dependencies from the C/C++ preprocessor input to this rule, even though
      // it technically should be added to the top-level rule.
      deps.addAll(
          pathResolver.filterBuildRuleInputs(
              cxxPreprocessorInput.getIncludes().getPrefixHeaders()));
      deps.addAll(
          pathResolver.filterBuildRuleInputs(
              cxxPreprocessorInput.getIncludes().getNameToPathMap().values()));
      deps.addAll(resolver.getAllRules(cxxPreprocessorInput.getRules()));

      // Add in the transitive preprocessor flags contributed by C/C++ library rules into the
      // NDK build.
      Iterable<String> ppflags = Iterables.concat(
          cxxPreprocessorInput.getPreprocessorFlags().get(CxxSource.Type.C),
          MoreIterables.zipAndConcat(
              Iterables.cycle("-I"),
              FluentIterable.from(cxxPreprocessorInput.getIncludeRoots())
                  .transform(Functions.toStringFunction())),
          MoreIterables.zipAndConcat(
              Iterables.cycle("-isystem"),
              FluentIterable.from(cxxPreprocessorInput.getIncludeRoots())
                  .transform(Functions.toStringFunction())));
      String localCflags = Joiner.on(' ').join(escapeForMakefile(ppflags));

      // Collect the native linkable input for all C/C++ library deps.  We search *through* other
      // NDK library rules.
      NativeLinkableInput nativeLinkableInput =
          NativeLinkables.getTransitiveNativeLinkableInput(
              cxxPlatform,
              params.getDeps(),
              Linker.LinkableDepType.SHARED,
              Predicates.or(
                  Predicates.instanceOf(NativeLinkable.class),
                  Predicates.instanceOf(NdkLibrary.class)),
              /* reverse */ true);

      // We add any dependencies from the native linkable input to this rule, even though
      // it technically should be added to the top-level rule.
      deps.addAll(pathResolver.filterBuildRuleInputs(nativeLinkableInput.getInputs()));

      // Add in the transitive native linkable flags contributed by C/C++ library rules into the
      // NDK build.
      String localLdflags = Joiner.on(' ').join(escapeForMakefile(nativeLinkableInput.getArgs()));

      // Write the relevant lines to the generated makefile.
      if (!localCflags.isEmpty() || !localLdflags.isEmpty()) {
        AndroidBinary.TargetCpuType targetCpuType = entry.getKey();
        String targetArchAbi = getTargetArchAbi(targetCpuType);

        outputLinesBuilder.add(String.format("ifeq ($(TARGET_ARCH_ABI),%s)", targetArchAbi));
        if (!localCflags.isEmpty()) {
          outputLinesBuilder.add("BUCK_DEP_CFLAGS=" + localCflags);
        }
        if (!localLdflags.isEmpty()) {
          outputLinesBuilder.add("BUCK_DEP_LDFLAGS=" + localLdflags);
        }
        outputLinesBuilder.add("endif");
        outputLinesBuilder.add("");
      }
    }

    outputLinesBuilder.add("include Android.mk");

    BuildTarget makefileTarget = BuildTarget
        .builder(params.getBuildTarget())
        .addFlavors(MAKEFILE_FLAVOR)
        .build();
    BuildRuleParams makefileParams = params.copyWithChanges(
        MAKEFILE_TYPE,
        makefileTarget,
        Suppliers.ofInstance(deps.build()),
        Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of()));
    final Path makefilePath = getGeneratedMakefilePath(params.getBuildTarget());
    final String contents = Joiner.on(System.lineSeparator()).join(outputLinesBuilder.build());

    return new AbstractBuildRule(makefileParams, pathResolver) {

      @Override
      protected ImmutableCollection<Path> getInputsToCompareToOutput() {
        return ImmutableList.of();
      }

      @Override
      protected RuleKey.Builder appendDetailsToRuleKey(RuleKey.Builder builder) {
        return builder
            .setReflectively("contents", contents)
            .setReflectively("output", makefilePath.toString());
      }

      @Override
      public ImmutableList<Step> getBuildSteps(
          BuildContext context,
          BuildableContext buildableContext) {
        buildableContext.recordArtifact(makefilePath);
        return ImmutableList.of(
            new MkdirStep(makefilePath.getParent()),
            new WriteFileStep(contents, makefilePath));
      }

      @Override
      public Path getPathToOutputFile() {
        return makefilePath;
      }

    };

  }

  @Override
  public <A extends Arg> NdkLibrary createBuildRule(
      final BuildRuleParams params,
      BuildRuleResolver resolver,
      A args) {

    BuildRule makefile = generateMakefile(params, resolver);
    resolver.addToIndex(makefile);

    final ImmutableSortedSet.Builder<SourcePath> srcs = ImmutableSortedSet.naturalOrder();

    try {
      final Path buildRulePath = params.getBuildTarget().getBasePath();
      final Path rootDirectory = params.getProjectFilesystem().resolve(buildRulePath);
      Files.walkFileTree(
          rootDirectory,
          EnumSet.of(FileVisitOption.FOLLOW_LINKS),
          /* maxDepth */ Integer.MAX_VALUE,
          new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                throws IOException {
              if (EXTENSIONS_REGEX.matcher(file.toString()).matches()) {
                srcs.add(
                    new PathSourcePath(
                        params.getProjectFilesystem(),
                        buildRulePath.resolve(rootDirectory.relativize(file))));
              }

              return super.visitFile(file, attrs);
            }
          });
    } catch (IOException e) {
      throw new RuntimeException(e);
    }

    return new NdkLibrary(
        params.copyWithExtraDeps(
            Suppliers.ofInstance(
                ImmutableSortedSet.<BuildRule>naturalOrder()
                    .addAll(params.getExtraDeps())
                    .add(makefile)
                    .build())),
        new SourcePathResolver(resolver),
        getGeneratedMakefilePath(params.getBuildTarget()),
        srcs.build(),
        args.flags.get(),
        args.isAsset.or(false),
        ndkVersion);
  }

  @SuppressFieldNotInitialized
  public static class Arg {
    public Optional<ImmutableList<String>> flags;
    public Optional<Boolean> isAsset;
    public Optional<ImmutableSortedSet<BuildTarget>> deps;
  }

}
