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

import com.facebook.buck.cxx.CxxBuckConfig;
import com.facebook.buck.cxx.CxxCompilables;
import com.facebook.buck.cxx.CxxLibraryDescription;
import com.facebook.buck.cxx.CxxPlatform;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargets;
import com.facebook.buck.model.Flavor;
import com.facebook.buck.model.FlavorDomain;
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.BuildTargetSourcePath;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.coercer.Either;
import com.facebook.buck.rules.coercer.SourceWithFlags;
import com.facebook.buck.util.HumanReadableException;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.io.Files;

import java.nio.file.Path;

public class ThriftCxxEnhancer implements ThriftLanguageSpecificEnhancer {

  private static final Flavor CPP_FLAVOR = ImmutableFlavor.of("cpp");
  private static final Flavor CPP2_FLAVOR = ImmutableFlavor.of("cpp2");

  private final ThriftBuckConfig thriftBuckConfig;
  private final CxxLibraryDescription cxxLibraryDescription;
  private final boolean cpp2;

  public ThriftCxxEnhancer(
      ThriftBuckConfig thriftBuckConfig,
      CxxBuckConfig cxxBuckConfig,
      FlavorDomain<CxxPlatform> cxxPlatforms,
      boolean cpp2) {
    this.thriftBuckConfig = thriftBuckConfig;
    this.cxxLibraryDescription = new CxxLibraryDescription(cxxBuckConfig, cxxPlatforms);
    this.cpp2 = cpp2;
  }

  @Override
  public String getLanguage() {
    return cpp2 ? "cpp2" : "cpp";
  }

  @Override
  public Flavor getFlavor() {
    return cpp2 ? CPP2_FLAVOR : CPP_FLAVOR;
  }

  // Return the gen-dir relative sources for the given services and options.
  @VisibleForTesting
  protected ImmutableList<String> getGeneratedThriftSources(
      ImmutableSet<String> options,
      String name,
      ImmutableList<String> services) {

    final String base = Files.getNameWithoutExtension(name);
    final boolean bootstrap = options.contains("bootstrap");
    final boolean layouts = options.contains("frozen");
    final boolean templates = cpp2 || options.contains("templates");
    final boolean perfhash = !cpp2 && options.contains("perfhash");

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

    sources.add(base + "_constants.h");
    sources.add(base + "_constants.cpp");

    sources.add(base + "_types.h");
    sources.add(base + "_types.cpp");

    if (templates) {
      sources.add(base + "_types.tcc");
    }

    if (layouts) {
      sources.add(base + "_layouts.h");
      sources.add(base + "_layouts.cpp");
    }

    if (!bootstrap && !cpp2) {
      sources.add(base + "_reflection.h");
      sources.add(base + "_reflection.cpp");
    }

    for (String service : services) {

      sources.add(service + ".h");
      sources.add(service + ".cpp");

      if (templates) {
        sources.add(service + ".tcc");
      }

      if (perfhash) {
        sources.add(service + "_gperf.tcc");
      }

    }

    return sources.build();
  }

  // Find all the generated sources and headers generated by these thrift sources.
  private CxxHeadersAndSources getThriftHeaderSourceSpec(
      BuildRuleParams params,
      ThriftConstructorArg args,
      ImmutableMap<String, ThriftSource> sources) {

    ImmutableSet<String> options =
        (cpp2 ? args.cpp2Options : args.cppOptions).or(ImmutableSet.<String>of());

    ImmutableMap.Builder<String, SourceWithFlags> cxxSourcesBuilder = ImmutableMap.builder();
    ImmutableMap.Builder<String, SourcePath> headersBuilder = ImmutableMap.builder();

    for (ImmutableMap.Entry<String, ThriftSource> ent : sources.entrySet()) {
      final String thriftName = ent.getKey();
      final ThriftSource source = ent.getValue();
      final Path outputDir = source.getOutputDir();

      for (String partialName : getGeneratedThriftSources(
          options,
          thriftName,
          source.getServices())) {

        String name = String.format("gen-%s/%s", getLanguage(), partialName);
        String extension = Files.getFileExtension(name);

        if (CxxCompilables.SOURCE_EXTENSIONS.contains(extension)) {
          cxxSourcesBuilder.put(
              name,
              SourceWithFlags.of(
                  new BuildTargetSourcePath(
                      source.getCompileRule().getProjectFilesystem(),
                      source.getCompileRule().getBuildTarget(),
                      outputDir.resolve(name))));
        } else if (CxxCompilables.HEADER_EXTENSIONS.contains(extension)) {
          headersBuilder.put(
              name,
              new BuildTargetSourcePath(
                  source.getCompileRule().getProjectFilesystem(),
                  source.getCompileRule().getBuildTarget(),
                  outputDir.resolve(name)));
        } else {
          throw new HumanReadableException(String.format(
              "%s: unexpected extension for \"%s\"",
              params.getBuildTarget(),
              name));
        }
      }
    }

    return new CxxHeadersAndSources(
        headersBuilder.build(),
        cxxSourcesBuilder.build());
  }

  @Override
  public BuildRule createBuildRule(
      BuildRuleParams params,
      BuildRuleResolver resolver,
      ThriftConstructorArg args,
      ImmutableMap<String, ThriftSource> sources,
      ImmutableSortedSet<BuildRule> deps) {

    // Grab all the sources and headers generated from the passed in thrift sources.
    CxxHeadersAndSources spec = getThriftHeaderSourceSpec(params, args, sources);

    // Add all the passed in language-specific thrift deps, and any C/C++ specific deps
    // passed in via the constructor arg.
    ImmutableSortedSet<BuildRule> allDeps =
        ImmutableSortedSet.<BuildRule>naturalOrder()
            .addAll(deps)
            .addAll(
                resolver.getAllRules(
                    (cpp2 ? args.cpp2Deps : args.cppDeps).or(ImmutableSortedSet.<BuildTarget>of())))
            .build();

    // Create language specific build params by using the deps we formed above.
    BuildRuleParams langParams = params.copyWithDeps(
        Suppliers.ofInstance(allDeps),
        Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of()));

    // Construct the C/C++ library description argument to pass to the
    CxxLibraryDescription.Arg langArgs = cxxLibraryDescription.createEmptyConstructorArg();
    langArgs.srcs =
        Optional.of(
            Either.<ImmutableList<SourceWithFlags>, ImmutableMap<String, SourceWithFlags>>ofRight(
                spec.getSources()));
    langArgs.exportedHeaders =
        Optional.of(
            Either.<ImmutableList<SourcePath>, ImmutableMap<String, SourcePath>>ofRight(
                spec.getHeaders()));

    return cxxLibraryDescription.createBuildRule(langParams, resolver, langArgs);
  }

  private ImmutableSet<BuildTarget> getImplicitDepsFromOptions(
      BuildTarget target,
      ImmutableSet<String> options) {

    ImmutableSet.Builder<BuildTarget> implicitDeps = ImmutableSet.builder();

    if (!options.contains("bootstrap")) {
      if (cpp2) {
        implicitDeps.add(thriftBuckConfig.getCpp2Dep());
      } else {
        implicitDeps.add(thriftBuckConfig.getCppDep());
      }
      implicitDeps.add(thriftBuckConfig.getCppReflectionDep());
    }

    if (options.contains("frozen2")) {
      implicitDeps.add(thriftBuckConfig.getCppFrozenDep());
    }

    if (options.contains("json")) {
      implicitDeps.add(thriftBuckConfig.getCppJsonDep());
    }

    if (cpp2 && options.contains("compatibility")) {
      implicitDeps.add(thriftBuckConfig.getCppDep());
      BuildTarget cppTarget = BuildTargets.createFlavoredBuildTarget(
          target.getUnflavoredBuildTarget(),
          CPP_FLAVOR);
      implicitDeps.add(cppTarget);
    }

    if (!cpp2 && options.contains("cob_style")) {
      implicitDeps.add(thriftBuckConfig.getCppAyncDep());
    }

    return implicitDeps.build();
  }

  @Override
  public ImmutableSet<BuildTarget> getImplicitDepsForTargetFromConstructorArg(
      BuildTarget target,
      ThriftConstructorArg arg) {
    Optional<ImmutableSet<String>> options = cpp2 ? arg.cpp2Options : arg.cppOptions;
    return getImplicitDepsFromOptions(target, options.or(ImmutableSet.<String>of()));
  }

  @Override
  public ImmutableSet<String> getOptions(
      BuildTarget target,
      ThriftConstructorArg args) {
    return ImmutableSet.<String>builder()
        .add(String.format("include_prefix=%s", target.getBasePath()))
        .addAll((cpp2 ? args.cpp2Options : args.cppOptions).or(ImmutableSet.<String>of()))
        .build();
  }

  private static class CxxHeadersAndSources {

    private final ImmutableMap<String, SourcePath> headers;
    private final ImmutableMap<String, SourceWithFlags> sources;

    public CxxHeadersAndSources(
        ImmutableMap<String, SourcePath> headers,
        ImmutableMap<String, SourceWithFlags> sources) {
      this.headers = headers;
      this.sources = sources;
    }

    public ImmutableMap<String, SourcePath> getHeaders() {
      return headers;
    }

    public ImmutableMap<String, SourceWithFlags> getSources() {
      return sources;
    }

  }

}
