/*
 * 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/Host.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) {
  }

  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__BIONIC_VERSIONER=1");
  cmd.push_back("-D__ANDROID_API__="s + std::to_string(type.api_level));
  cmd.push_back("-D_FORTIFY_SOURCE=2");
  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, "versioner", 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, *diags)) {
    errx(1, "failed to create CompilerInvocation");
  }

  clang::CompilerInstance Compiler;

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