/*
 * 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/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/Option/Option.h>
#include <llvm/Support/VirtualFileSystem.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<llvm::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 llvm::opt::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<llvm::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<llvm::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;

  Compiler.setInvocation(std::move(invocation));
  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");
  }
}
