/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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.
 */

#include "Driver.h"

#include <err.h>
#include <string.h>

#include <chrono>
#include <mutex>
#include <string>
#include <thread>
#include <unordered_map>
#include <vector>

#include <clang/AST/ASTConsumer.h>
#include <clang/Basic/Diagnostic.h>
#include <clang/Basic/TargetInfo.h>
#include <clang/Basic/VirtualFileSystem.h>
#include <clang/Driver/Compilation.h>
#include <clang/Driver/Driver.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/CompilerInvocation.h>
#include <clang/Frontend/FrontendAction.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Frontend/Utils.h>
#include <clang/FrontendTool/Utils.h>
#include <llvm/ADT/IntrusiveRefCntPtr.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/ADT/StringRef.h>
#include <llvm/Config/config.h>

#include "Arch.h"
#include "DeclarationDatabase.h"
#include "versioner.h"

using namespace std::chrono_literals;
using namespace std::string_literals;

using namespace clang;

class VersionerASTConsumer : public clang::ASTConsumer {
 public:
  HeaderDatabase* header_database;
  CompilationType type;

  VersionerASTConsumer(HeaderDatabase* header_database, CompilationType type)
      : header_database(header_database), type(type) {
  }

  virtual void HandleTranslationUnit(ASTContext& ctx) override {
    header_database->parseAST(type, ctx);
  }
};

class VersionerASTAction : public clang::ASTFrontendAction {
 public:
  HeaderDatabase* header_database;
  CompilationType type;

  VersionerASTAction(HeaderDatabase* header_database, CompilationType type)
      : header_database(header_database), type(type) {
  }

  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance&, llvm::StringRef) override {
    return std::make_unique<VersionerASTConsumer>(header_database, type);
  }
};

static IntrusiveRefCntPtr<DiagnosticsEngine> constructDiags() {
  IntrusiveRefCntPtr<DiagnosticOptions> diag_opts(new DiagnosticOptions());
  auto diag_printer = std::make_unique<TextDiagnosticPrinter>(llvm::errs(), diag_opts.get());
  IntrusiveRefCntPtr<DiagnosticIDs> diag_ids(new DiagnosticIDs());
  IntrusiveRefCntPtr<DiagnosticsEngine> diags(
      new DiagnosticsEngine(diag_ids.get(), diag_opts.get(), diag_printer.release()));
  return diags;
}

// clang's driver is slow compared to the work it performs to compile our headers.
// Run it once to generate flags for each target, and memoize the results.
static std::unordered_map<CompilationType, std::vector<std::string>> cc1_flags;
static const char* filename_placeholder = "__VERSIONER_PLACEHOLDER__";
static void generateTargetCC1Flags(llvm::IntrusiveRefCntPtr<clang::vfs::FileSystem> vfs,
                                   CompilationType type,
                                   const std::vector<std::string>& include_dirs) {
  std::vector<std::string> cmd = { "versioner" };
  if (type.cpp) {
    cmd.push_back("-std=gnu++11");
    cmd.push_back("-x");
    cmd.push_back("c++");
  } else {
    cmd.push_back("-std=gnu11");
    cmd.push_back("-x");
    cmd.push_back("c");
  }

  cmd.push_back("-fsyntax-only");

  cmd.push_back("-Wall");
  cmd.push_back("-Wextra");
  cmd.push_back("-Weverything");
  cmd.push_back("-Werror");
  cmd.push_back("-Wundef");
  cmd.push_back("-Wno-unused-macros");
  cmd.push_back("-Wno-unused-function");
  cmd.push_back("-Wno-unused-variable");
  cmd.push_back("-Wno-unknown-attributes");
  cmd.push_back("-Wno-pragma-once-outside-header");

  cmd.push_back("-target");
  cmd.push_back(arch_targets[type.arch]);

  cmd.push_back("-DANDROID");
  cmd.push_back("-D__ANDROID_API__="s + std::to_string(type.api_level));
  // FIXME: Re-enable FORTIFY properly once our clang in external/ is new enough
  // to support diagnose_if without giving us syntax errors.
#if 0
  cmd.push_back("-D_FORTIFY_SOURCE=2");
#else
  cmd.push_back("-D_FORTIFY_SOURCE=0");
  cmd.push_back("-D__BIONIC_DECLARE_FORTIFY_HELPERS");
#endif
  cmd.push_back("-D_GNU_SOURCE");
  cmd.push_back("-D_FILE_OFFSET_BITS="s + std::to_string(type.file_offset_bits));

  cmd.push_back("-nostdinc");

  if (add_include) {
    cmd.push_back("-include");
    cmd.push_back("android/versioning.h");
  }

  for (const auto& dir : include_dirs) {
    cmd.push_back("-isystem");
    cmd.push_back(dir);
  }

  cmd.push_back("-include");
  cmd.push_back(filename_placeholder);
  cmd.push_back("-");

  auto diags = constructDiags();
  driver::Driver driver("versioner", llvm::sys::getDefaultTargetTriple(), *diags, vfs);
  driver.setCheckInputsExist(false);

  llvm::SmallVector<const char*, 32> driver_args;
  for (const std::string& str : cmd) {
    driver_args.push_back(str.c_str());
  }

  std::unique_ptr<driver::Compilation> Compilation(driver.BuildCompilation(driver_args));
  const driver::JobList& jobs = Compilation->getJobs();
  if (jobs.size() != 1) {
    errx(1, "driver returned %zu jobs for %s", jobs.size(), to_string(type).c_str());
  }

  const driver::Command& driver_cmd = llvm::cast<driver::Command>(*jobs.begin());
  const driver::ArgStringList& cc_args = driver_cmd.getArguments();

  if (cc_args.size() == 0) {
    errx(1, "driver returned empty command for %s", to_string(type).c_str());
  }

  std::vector<std::string> result(cc_args.begin(), cc_args.end());

  {
    static std::mutex cc1_init_mutex;
    std::unique_lock<std::mutex> lock(cc1_init_mutex);
    if (cc1_flags.count(type) > 0) {
      errx(1, "attemped to generate cc1 flags for existing CompilationType %s",
           to_string(type).c_str());
    }

    cc1_flags.emplace(std::make_pair(type, std::move(result)));
  }
}

static std::vector<const char*> getCC1Command(CompilationType type, const std::string& filename) {
  const auto& target_flag_it = cc1_flags.find(type);
  if (target_flag_it == cc1_flags.end()) {
    errx(1, "failed to find target flags for CompilationType %s", to_string(type).c_str());
  }

  std::vector<const char*> result;
  for (const std::string& flag : target_flag_it->second) {
    if (flag == "-disable-free") {
      continue;
    } else if (flag == filename_placeholder) {
      result.push_back(filename.c_str());
    } else {
      result.push_back(flag.c_str());
    }
  }
  return result;
}

void initializeTargetCC1FlagCache(llvm::IntrusiveRefCntPtr<clang::vfs::FileSystem> vfs,
                                  const std::set<CompilationType>& types,
                                  const std::unordered_map<Arch, CompilationRequirements>& reqs) {
  if (!cc1_flags.empty()) {
    errx(1, "reinitializing target CC1 flag cache?");
  }

  auto start = std::chrono::high_resolution_clock::now();
  std::vector<std::thread> threads;
  for (const CompilationType type : types) {
    threads.emplace_back([type, &vfs, &reqs]() {
      const auto& arch_req_it = reqs.find(type.arch);
      if (arch_req_it == reqs.end()) {
        errx(1, "CompilationRequirement map missing entry for CompilationType %s",
             to_string(type).c_str());
      }

      generateTargetCC1Flags(vfs, type, arch_req_it->second.dependencies);
    });
  }
  for (auto& thread : threads) {
    thread.join();
  }
  auto end = std::chrono::high_resolution_clock::now();

  if (verbose) {
    auto diff = (end - start) / 1.0ms;
    printf("Generated compiler flags for %zu targets in %0.2Lfms\n", types.size(), diff);
  }

  if (cc1_flags.empty()) {
    errx(1, "failed to initialize target CC1 flag cache");
  }
}

void compileHeader(llvm::IntrusiveRefCntPtr<clang::vfs::FileSystem> vfs,
                   HeaderDatabase* header_database, CompilationType type,
                   const std::string& filename) {
  auto diags = constructDiags();
  std::vector<const char*> cc1_flags = getCC1Command(type, filename);
  auto invocation = std::make_unique<CompilerInvocation>();
  if (!CompilerInvocation::CreateFromArgs(*invocation.get(), &cc1_flags.front(),
                                          &cc1_flags.front() + cc1_flags.size(), *diags)) {
    errx(1, "failed to create CompilerInvocation");
  }

  clang::CompilerInstance Compiler;

// Remove the workaround once b/35936936 is fixed.
#if LLVM_VERSION_MAJOR >= 5
  Compiler.setInvocation(std::move(invocation));
#else
  Compiler.setInvocation(invocation.release());
#endif

  Compiler.setDiagnostics(diags.get());
  Compiler.setVirtualFileSystem(vfs);

  VersionerASTAction versioner_action(header_database, type);
  if (!Compiler.ExecuteAction(versioner_action)) {
    errx(1, "compilation generated warnings or errors");
  }

  if (diags->getNumWarnings() || diags->hasErrorOccurred()) {
    errx(1, "compilation generated warnings or errors");
  }
}
