/*
 * Copyright 2017 The Bazel Authors. All rights reserved.
 *
 * 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.google.idea.blaze.cpp;

import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.ideinfo.CToolchainIdeInfo;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.ideinfo.TargetKey;
import com.google.idea.blaze.base.ideinfo.TargetMap;
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.Scope;
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.scope.scopes.TimingScope;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.jetbrains.cidr.toolchains.CompilerInfoCache;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/**
 * Converts {@link CToolchainIdeInfo} to interfaces used by {@link
 * com.jetbrains.cidr.lang.workspace.OCResolveConfiguration}
 */
final class BlazeConfigurationToolchainResolver {
  private static final Logger logger =
      Logger.getInstance(BlazeConfigurationToolchainResolver.class);

  private BlazeConfigurationToolchainResolver() {}

  /** Returns the toolchain used by each target */
  static ImmutableMap<TargetKey, CToolchainIdeInfo> buildToolchainLookupMap(
      BlazeContext context, TargetMap targetMap) {
    return Scope.push(
        context,
        childContext -> {
          childContext.push(new TimingScope("Build toolchain lookup map"));

          Map<TargetKey, CToolchainIdeInfo> toolchains = Maps.newLinkedHashMap();
          for (TargetIdeInfo target : targetMap.targets()) {
            CToolchainIdeInfo cToolchainIdeInfo = target.cToolchainIdeInfo;
            if (cToolchainIdeInfo != null) {
              toolchains.put(target.key, cToolchainIdeInfo);
            }
          }

          ImmutableMap.Builder<TargetKey, CToolchainIdeInfo> lookupTable = ImmutableMap.builder();
          for (TargetIdeInfo target : targetMap.targets()) {
            if (target.kind.languageClass != LanguageClass.C || target.kind == Kind.CC_TOOLCHAIN) {
              continue;
            }
            List<TargetKey> toolchainDeps =
                target
                    .dependencies
                    .stream()
                    .map(dep -> dep.targetKey)
                    .filter(toolchains::containsKey)
                    .collect(Collectors.toList());
            if (toolchainDeps.size() != 1) {
              issueToolchainWarning(context, target, toolchainDeps);
            }
            if (!toolchainDeps.isEmpty()) {
              TargetKey toolchainKey = toolchainDeps.get(0);
              CToolchainIdeInfo toolchainInfo = toolchains.get(toolchainKey);
              lookupTable.put(target.key, toolchainInfo);
            } else {
              CToolchainIdeInfo arbitraryToolchain = Iterables.getFirst(toolchains.values(), null);
              if (arbitraryToolchain != null) {
                lookupTable.put(target.key, arbitraryToolchain);
              }
            }
          }
          return lookupTable.build();
        });
  }

  private static void issueToolchainWarning(
      BlazeContext context, TargetIdeInfo target, List<TargetKey> toolchainDeps) {
    String warningMessage =
        String.format(
            "cc target %s does not depend on exactly 1 cc toolchain. " + " Found %d toolchains.",
            target.key, toolchainDeps.size());
    if (usesAppleCcToolchain(target)) {
      logger.warn(warningMessage + " (apple_cc_toolchain)");
    } else {
      IssueOutput.warn(warningMessage).submit(context);
    }
  }

  private static boolean usesAppleCcToolchain(TargetIdeInfo target) {
    return target
        .dependencies
        .stream()
        .anyMatch(dep -> dep.targetKey.label.toString().startsWith("//tools/osx/crosstool"));
  }

  /** Returns the compiler settings for each toolchain. */
  static ImmutableMap<CToolchainIdeInfo, BlazeCompilerSettings> buildCompilerSettingsMap(
      BlazeContext context,
      Project project,
      WorkspaceRoot workspaceRoot,
      ImmutableMap<TargetKey, CToolchainIdeInfo> toolchainLookupMap,
      WorkspacePathResolver workspacePathResolver,
      CompilerInfoCache compilerInfoCache,
      ImmutableMap<CToolchainIdeInfo, BlazeCompilerSettings> oldCompilerSettings) {
    return Scope.push(
        context,
        childContext -> {
          childContext.push(new TimingScope("Build compiler settings map"));
          return doBuildCompilerSettingsMap(
              context,
              project,
              workspaceRoot,
              toolchainLookupMap,
              workspacePathResolver,
              compilerInfoCache,
              oldCompilerSettings);
        });
  }

  private static ImmutableMap<CToolchainIdeInfo, BlazeCompilerSettings> doBuildCompilerSettingsMap(
      BlazeContext context,
      Project project,
      WorkspaceRoot workspaceRoot,
      ImmutableMap<TargetKey, CToolchainIdeInfo> toolchainLookupMap,
      WorkspacePathResolver workspacePathResolver,
      CompilerInfoCache compilerInfoCache,
      ImmutableMap<CToolchainIdeInfo, BlazeCompilerSettings> oldCompilerSettings) {
    Set<CToolchainIdeInfo> toolchains =
        toolchainLookupMap.values().stream().distinct().collect(Collectors.toSet());
    List<ListenableFuture<Map.Entry<CToolchainIdeInfo, BlazeCompilerSettings>>>
        compilerSettingsFutures = new ArrayList<>();
    for (CToolchainIdeInfo toolchain : toolchains) {
      compilerSettingsFutures.add(
          submit(
              () -> {
                File cppExecutable = resolveCompilerExecutable(toolchain, workspacePathResolver);
                if (cppExecutable == null) {
                  logger.warn(
                      String.format(
                          "Unable to find compiler executable: %s for toolchain %s",
                          toolchain.cppExecutable.toString(), toolchain));
                  return null;
                }
                String compilerVersion =
                    CompilerVersionChecker.getInstance()
                        .checkCompilerVersion(workspaceRoot, cppExecutable);
                if (compilerVersion == null) {
                  logger.warn(
                      String.format(
                          "Unable to determine version of compiler: %s for toolchain %s",
                          cppExecutable, toolchain));
                  return null;
                }
                BlazeCompilerSettings oldSettings = oldCompilerSettings.get(toolchain);
                if (oldSettings != null
                    && oldSettings.getCompilerVersion().equals(compilerVersion)) {
                  return new SimpleImmutableEntry<>(toolchain, oldSettings);
                }
                BlazeCompilerSettings settings =
                    createBlazeCompilerSettings(
                        project, toolchain, cppExecutable, compilerVersion, compilerInfoCache);
                if (settings == null) {
                  return null;
                }
                return new SimpleImmutableEntry<>(toolchain, settings);
              }));
    }
    ImmutableMap.Builder<CToolchainIdeInfo, BlazeCompilerSettings> compilerSettingsMap =
        ImmutableMap.builder();
    try {
      List<Map.Entry<CToolchainIdeInfo, BlazeCompilerSettings>> createdSettings =
          Futures.allAsList(compilerSettingsFutures).get();
      for (Map.Entry<CToolchainIdeInfo, BlazeCompilerSettings> createdSetting : createdSettings) {
        if (createdSetting != null) {
          compilerSettingsMap.put(createdSetting);
        }
      }
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      context.setCancelled();
    } catch (ExecutionException e) {
      IssueOutput.error("Could not build C compiler settings map: " + e).submit(context);
      logger.error("Could not build C compiler settings map", e);
    }
    return compilerSettingsMap.build();
  }

  @Nullable
  private static BlazeCompilerSettings createBlazeCompilerSettings(
      Project project,
      CToolchainIdeInfo toolchainIdeInfo,
      File cppExecutable,
      String compilerVersion,
      CompilerInfoCache compilerInfoCache) {
    File compilerWrapper = createCompilerExecutableWrapper(cppExecutable);
    if (compilerWrapper == null) {
      return null;
    }
    ImmutableList.Builder<String> cFlagsBuilder = ImmutableList.builder();
    cFlagsBuilder.addAll(toolchainIdeInfo.baseCompilerOptions);
    cFlagsBuilder.addAll(toolchainIdeInfo.cCompilerOptions);
    cFlagsBuilder.addAll(toolchainIdeInfo.unfilteredCompilerOptions);

    ImmutableList.Builder<String> cppFlagsBuilder = ImmutableList.builder();
    cppFlagsBuilder.addAll(toolchainIdeInfo.baseCompilerOptions);
    cppFlagsBuilder.addAll(toolchainIdeInfo.cppCompilerOptions);
    cppFlagsBuilder.addAll(toolchainIdeInfo.unfilteredCompilerOptions);
    return new BlazeCompilerSettings(
        project,
        compilerWrapper,
        compilerWrapper,
        cFlagsBuilder.build(),
        cppFlagsBuilder.build(),
        compilerVersion,
        compilerInfoCache);
  }

  @Nullable
  private static File resolveCompilerExecutable(
      CToolchainIdeInfo toolchainIdeInfo, WorkspacePathResolver workspacePathResolver) {
    File cppExecutable = toolchainIdeInfo.cppExecutable.getAbsoluteOrRelativeFile();
    if (cppExecutable != null && !cppExecutable.isAbsolute()) {
      cppExecutable = workspacePathResolver.resolveToFile(cppExecutable.getPath());
    }
    return cppExecutable;
  }

  /**
   * Create a wrapper script that transforms the CLion compiler invocation into a safe invocation of
   * the compiler script that blaze uses.
   *
   * <p>CLion passes arguments to the compiler in an arguments file. The c toolchain compiler
   * wrapper script doesn't handle arguments files, so we need to move the compiler arguments from
   * the file to the command line.
   *
   * @param blazeCompilerExecutableFile blaze compiler wrapper
   * @return The wrapper script that CLion can call.
   */
  @Nullable
  private static File createCompilerExecutableWrapper(File blazeCompilerExecutableFile) {
    try {
      File blazeCompilerWrapper =
          FileUtil.createTempFile("blaze_compiler", ".sh", true /* deleteOnExit */);
      if (!blazeCompilerWrapper.setExecutable(true)) {
        logger.warn("Unable to make compiler wrapper script executable: " + blazeCompilerWrapper);
        return null;
      }
      ImmutableList<String> compilerWrapperScriptLines =
          ImmutableList.of(
              "#!/bin/bash",
              "",
              "# The c toolchain compiler wrapper script doesn't handle arguments files, so we",
              "# need to move the compiler arguments from the file to the command line.",
              "",
              "if [ $# -ne 2 ]; then",
              "  echo \"Usage: $0 @arg-file compile-file\"",
              "  exit 2;",
              "fi",
              "",
              "if [[ $1 != @* ]]; then",
              "  echo \"Usage: $0 @arg-file compile-file\"",
              "  exit 3;",
              "fi",
              "",
              " # Remove the @ before the arguments file path",
              "ARG_FILE=${1#@}",
              "# The actual compiler wrapper script we get from blaze",
              "EXE=" + blazeCompilerExecutableFile.getPath(),
              "# Read in the arguments file so we can pass the arguments on the command line.",
              "ARGS=`cat $ARG_FILE`",
              "$EXE $ARGS $2");

      try (PrintWriter pw = new PrintWriter(blazeCompilerWrapper, UTF_8.name())) {
        compilerWrapperScriptLines.forEach(pw::println);
      }
      return blazeCompilerWrapper;
    } catch (IOException e) {
      logger.warn(
          "Unable to write compiler wrapper script executable: " + blazeCompilerExecutableFile, e);
      return null;
    }
  }

  private static <T> ListenableFuture<T> submit(Callable<T> callable) {
    return BlazeExecutor.getInstance().submit(callable);
  }
}
