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

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.BuildRule;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.BuildRuleType;
import com.facebook.buck.rules.ImmutableBuildRuleType;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.coercer.SourceWithFlags;
import com.facebook.buck.util.HumanReadableException;
import com.facebook.buck.util.MoreIterables;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Suppliers;
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 com.google.common.io.Files;

import java.nio.file.Path;

public class CxxCompilableEnhancer {

  private static final BuildRuleType COMPILE_TYPE = ImmutableBuildRuleType.of("compile");

  private CxxCompilableEnhancer() {}

  /**
   * Prefixes each of the given assembler arguments with "-Xassembler" so that the compiler
   * assembler driver will pass these arguments directly down to the linker rather than
   * interpreting them itself.
   *
   * e.g. ["--fatal-warnings"] -> ["-Xassembler", "--fatal-warnings"]
   *
   * @param args arguments for the assembler.
   * @return arguments to be passed to the compiler assembler driver.
   */
  public static Iterable<String> iXassembler(Iterable<String> args) {
    return MoreIterables.zipAndConcat(
        Iterables.cycle("-Xassembler"),
        args);
  }

  /**
   * Resolve the map of names to SourcePaths to a map of names to CxxSource objects.
   */
  public static ImmutableMap<String, CxxSource> resolveCxxSources(
      ImmutableMap<String, SourceWithFlags> sources) {

    ImmutableMap.Builder<String, CxxSource> cxxSources = ImmutableMap.builder();

    // For each entry in the input C/C++ source, build a CxxSource object to wrap
    // it's name, input path, and output object file path.
    for (ImmutableMap.Entry<String, SourceWithFlags> ent : sources.entrySet()) {
      String extension = Files.getFileExtension(ent.getKey());
      Optional<CxxSource.Type> type = CxxSource.Type.fromExtension(extension);
      if (!type.isPresent()) {
        throw new HumanReadableException(
            "invalid extension \"%s\": %s",
            extension,
            ent.getKey());
      }
      cxxSources.put(
          ent.getKey(),
          ImmutableCxxSource.of(
              type.get(),
              ent.getValue().getSourcePath(),
              ent.getValue().getFlags()));
    }

    return cxxSources.build();
  }

  /**
   * @return the object file name for the given source name.
   */
  private static String getOutputName(String name) {
    return name + ".o";
  }

  /**
   * @return a build target for a {@link CxxCompile} rule for the source with the given name.
   */
  public static BuildTarget createCompileBuildTarget(
      BuildTarget target,
      Flavor platform,
      String name,
      boolean pic) {
    return BuildTarget
        .builder(target)
        .addFlavors(platform)
        .addFlavors(
            ImmutableFlavor.of(
                String.format(
                    "compile-%s%s",
                    pic ? "pic-" : "",
                    getOutputName(name)
                        .replace('/', '-')
                        .replace('.', '-')
                        .replace('+', '-')
                        .replace(' ', '-'))))
        .build();
  }

  /**
   * @return the output path for an object file compiled from the source with the given name.
   */
  public static Path getCompileOutputPath(BuildTarget target, String name) {
    return BuildTargets.getBinPath(target, "%s").resolve(getOutputName(name));
  }

  /**
   * @return a {@link CxxCompile} rule that preprocesses, compiles, and assembles the given
   *    {@link CxxSource}.
   */
  public static CxxCompile createCompileBuildRule(
      BuildRuleParams params,
      BuildRuleResolver resolver,
      CxxPlatform platform,
      ImmutableList<String> compilerFlags,
      boolean pic,
      String name,
      CxxSource source) {
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);

    Preconditions.checkArgument(CxxSourceTypes.isCompilableType(source.getType()));

    BuildTarget target = createCompileBuildTarget(
        params.getBuildTarget(),
        platform.getFlavor(),
        name,
        pic);

    ImmutableSortedSet.Builder<BuildRule> dependencies = ImmutableSortedSet.naturalOrder();

    // If a build rule generates our input source, add that as a dependency.
    dependencies.addAll(pathResolver.filterBuildRuleInputs(ImmutableList.of(source.getPath())));

    // Pick the compiler to use.  Basically, if we're dealing with C++ sources, use the C++
    // compiler, and the C compiler for everything.
    Tool compiler;
    if (CxxSourceTypes.needsCxxCompiler(source.getType())) {
      compiler = platform.getCxx();
    } else {
      compiler = platform.getCc();
    }

    ImmutableList.Builder<String> args = ImmutableList.builder();

    // TODO(#5393669): We need to handle compiler drivers that don't support certain language
    // options (e.g. the android NDK compilers don't support "c-cpp-output", although they can
    // auto-detect via the extension).  For the time being, we just fall back to the default
    // of letting the compiler driver auto-detecting the language type via the extensions which
    // should work, since we require proper extensions in the descriptions.
    //args.add("-x", source.getType().getLanguage());

    // If we're dealing with a C source that can be compiled, add the platform C compiler flags.
    if (source.getType() == CxxSource.Type.C_CPP_OUTPUT ||
        source.getType() == CxxSource.Type.OBJC_CPP_OUTPUT) {
      args.addAll(platform.getCflags());
    }

    // If we're dealing with a C++ source that can be compiled, add the platform C++ compiler
    // flags.
    if (source.getType() == CxxSource.Type.CXX_CPP_OUTPUT ||
        source.getType() == CxxSource.Type.OBJCXX_CPP_OUTPUT) {
      args.addAll(platform.getCxxflags());
    }

    // Add in explicit additional compiler flags, if we're compiling.
    if (source.getType() == CxxSource.Type.C_CPP_OUTPUT ||
        source.getType() == CxxSource.Type.OBJC_CPP_OUTPUT ||
        source.getType() == CxxSource.Type.CXX_CPP_OUTPUT ||
        source.getType() == CxxSource.Type.OBJCXX_CPP_OUTPUT) {
      args.addAll(compilerFlags);
    }

    // All source types require assembling, so add in platform-specific assembler flags.
    args.addAll(iXassembler(platform.getAsflags()));

    // If we're using pic, add in the appropriate flag.
    if (pic) {
      args.add("-fPIC");
    }

    // Add custom per-file flags.
    args.addAll(source.getFlags());

    // Build the CxxCompile rule and add it to our sorted set of build rules.
    return new CxxCompile(
        params.copyWithChanges(
            COMPILE_TYPE,
            target,
            Suppliers.ofInstance(dependencies.build()),
            Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of())),
        pathResolver,
        compiler,
        Optional.<CxxCompile.Plugin>absent(),
        args.build(),
        getCompileOutputPath(target, name),
        source.getPath(),
        platform.getDebugPathSanitizer());
  }

  /**
   * @return a set of {@link CxxCompile} rules which compile and assemble the given input
   *     {@link CxxSource} sources.
   */
  public static ImmutableSortedSet<BuildRule> createCompileBuildRules(
      BuildRuleParams params,
      BuildRuleResolver resolver,
      CxxPlatform platform,
      ImmutableList<String> compilerFlags,
      boolean pic,
      ImmutableMap<String, CxxSource> sources) {

    ImmutableSortedSet.Builder<BuildRule> rules = ImmutableSortedSet.naturalOrder();

    // Iterate over the input C/C++ sources that we need to compile and assemble and generate
    // build rules for them.
    for (ImmutableMap.Entry<String, CxxSource> entry : sources.entrySet()) {
      rules.add(createCompileBuildRule(
          params,
          resolver,
          platform,
          compilerFlags,
          pic,
          entry.getKey(),
          entry.getValue()));
    }

    return rules.build();
  }

}
