// Copyright (c) 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "tools/gn/qt_creator_writer.h"

#include <optional>
#include <set>
#include <sstream>
#include <string>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/strings/utf_string_conversions.h"

#include "tools/gn/builder.h"
#include "tools/gn/config_values_extractors.h"
#include "tools/gn/deps_iterator.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/label.h"
#include "tools/gn/loader.h"

namespace {
base::FilePath::CharType kProjectDirName[] =
    FILE_PATH_LITERAL("qtcreator_project");
base::FilePath::CharType kProjectName[] = FILE_PATH_LITERAL("all");
base::FilePath::CharType kMainProjectFileSuffix[] =
    FILE_PATH_LITERAL(".creator");
base::FilePath::CharType kSourcesFileSuffix[] = FILE_PATH_LITERAL(".files");
base::FilePath::CharType kIncludesFileSuffix[] = FILE_PATH_LITERAL(".includes");
base::FilePath::CharType kDefinesFileSuffix[] = FILE_PATH_LITERAL(".config");
}  // namespace

// static
bool QtCreatorWriter::RunAndWriteFile(const BuildSettings* build_settings,
                                      const Builder& builder,
                                      Err* err,
                                      const std::string& root_target) {
  base::FilePath project_dir =
      build_settings->GetFullPath(build_settings->build_dir())
          .Append(kProjectDirName);
  if (!base::DirectoryExists(project_dir)) {
    base::File::Error error;
    if (!base::CreateDirectoryAndGetError(project_dir, &error)) {
      *err =
          Err(Location(), "Could not create the QtCreator project directory '" +
                              FilePathToUTF8(project_dir) +
                              "': " + base::File::ErrorToString(error));
      return false;
    }
  }

  base::FilePath project_prefix = project_dir.Append(kProjectName);
  QtCreatorWriter gen(build_settings, builder, project_prefix, root_target);
  gen.Run();
  if (gen.err_.has_error()) {
    *err = gen.err_;
    return false;
  }
  return true;
}

QtCreatorWriter::QtCreatorWriter(const BuildSettings* build_settings,
                                 const Builder& builder,
                                 const base::FilePath& project_prefix,
                                 const std::string& root_target_name)
    : build_settings_(build_settings),
      builder_(builder),
      project_prefix_(project_prefix),
      root_target_name_(root_target_name) {}

QtCreatorWriter::~QtCreatorWriter() = default;

void QtCreatorWriter::CollectDeps(const Target* target) {
  for (const auto& dep : target->GetDeps(Target::DEPS_ALL)) {
    const Target* dep_target = dep.ptr;
    if (targets_.count(dep_target))
      continue;
    targets_.insert(dep_target);
    CollectDeps(dep_target);
  }
}

bool QtCreatorWriter::DiscoverTargets() {
  auto all_targets = builder_.GetAllResolvedTargets();

  if (root_target_name_.empty()) {
    targets_ = std::set<const Target*>(all_targets.begin(), all_targets.end());
    return true;
  }

  const Target* root_target = nullptr;
  for (const Target* target : all_targets) {
    if (target->label().name() == root_target_name_) {
      root_target = target;
      break;
    }
  }

  if (!root_target) {
    err_ = Err(Location(), "Target '" + root_target_name_ + "' not found.");
    return false;
  }

  targets_.insert(root_target);
  CollectDeps(root_target);
  return true;
}

void QtCreatorWriter::AddToSources(const Target::FileList& files) {
  for (const SourceFile& file : files) {
    const std::string& file_path =
        FilePathToUTF8(build_settings_->GetFullPath(file));
    sources_.insert(file_path);
  }
}

namespace QtCreatorWriterUtils {

enum class CVersion {
  C99,
  C11,
};

enum class CxxVersion {
  CXX98,
  CXX03,
  CXX11,
  CXX14,
  CXX17,
};

std::string ToMacro(CVersion version) {
  const std::string s = "__STDC_VERSION__";

  switch (version) {
    case CVersion::C99:
      return s + " 199901L";
    case CVersion::C11:
      return s + " 201112L";
  }

  return std::string();
}

std::string ToMacro(CxxVersion version) {
  const std::string name = "__cplusplus";

  switch (version) {
    case CxxVersion::CXX98:
    case CxxVersion::CXX03:
      return name + " 199711L";
    case CxxVersion::CXX11:
      return name + " 201103L";
    case CxxVersion::CXX14:
      return name + " 201402L";
    case CxxVersion::CXX17:
      return name + " 201703L";
  }

  return std::string();
}

const std::map<std::string, CVersion> kFlagToCVersion{
    {"-std=gnu99", CVersion::C99},
    {"-std=c99", CVersion::C99},
    {"-std=gnu11", CVersion::C11},
    {"-std=c11", CVersion::C11}};

const std::map<std::string, CxxVersion> kFlagToCxxVersion{
    {"-std=gnu++11", CxxVersion::CXX11}, {"-std=c++11", CxxVersion::CXX11},
    {"-std=gnu++98", CxxVersion::CXX98}, {"-std=c++98", CxxVersion::CXX98},
    {"-std=gnu++03", CxxVersion::CXX03}, {"-std=c++03", CxxVersion::CXX03},
    {"-std=gnu++14", CxxVersion::CXX14}, {"-std=c++14", CxxVersion::CXX14},
    {"-std=c++1y", CxxVersion::CXX14},   {"-std=gnu++17", CxxVersion::CXX17},
    {"-std=c++17", CxxVersion::CXX17},   {"-std=c++1z", CxxVersion::CXX17},
};

template <typename Enum>
struct CompVersion {
  bool operator()(Enum a, Enum b) {
    return static_cast<int>(a) < static_cast<int>(b);
  }
};

struct CompilerOptions {
  std::optional<CVersion> c_version_;
  std::optional<CxxVersion> cxx_version_;

  void SetCVersion(CVersion ver) { SetVersionImpl(c_version_, ver); }

  void SetCxxVersion(CxxVersion ver) { SetVersionImpl(cxx_version_, ver); }

 private:
  template <typename Version>
  void SetVersionImpl(std::optional<Version>& cur_ver, Version ver) {
    if (cur_ver)
      cur_ver = std::max(*cur_ver, ver, CompVersion<Version>{});
    else
      cur_ver = ver;
  }
};

void ParseCompilerOption(const std::string& flag, CompilerOptions* options) {
  auto c_ver = kFlagToCVersion.find(flag);
  if (c_ver != kFlagToCVersion.end())
    options->SetCVersion(c_ver->second);

  auto cxx_ver = kFlagToCxxVersion.find(flag);
  if (cxx_ver != kFlagToCxxVersion.end())
    options->SetCxxVersion(cxx_ver->second);
}

void ParseCompilerOptions(const std::vector<std::string>& cflags,
                          CompilerOptions* options) {
  for (const std::string& flag : cflags)
    ParseCompilerOption(flag, options);
}

}  // namespace QtCreatorWriterUtils

void QtCreatorWriter::HandleTarget(const Target* target) {
  using namespace QtCreatorWriterUtils;

  SourceFile build_file = Loader::BuildFileForLabel(target->label());
  sources_.insert(FilePathToUTF8(build_settings_->GetFullPath(build_file)));
  AddToSources(target->settings()->import_manager().GetImportedFiles());

  AddToSources(target->sources());
  AddToSources(target->public_headers());

  for (ConfigValuesIterator it(target); !it.done(); it.Next()) {
    for (const auto& input : it.cur().inputs())
      sources_.insert(FilePathToUTF8(build_settings_->GetFullPath(input)));

    SourceFile precompiled_source = it.cur().precompiled_source();
    if (!precompiled_source.is_null()) {
      sources_.insert(
          FilePathToUTF8(build_settings_->GetFullPath(precompiled_source)));
    }

    for (const SourceDir& include_dir : it.cur().include_dirs()) {
      includes_.insert(
          FilePathToUTF8(build_settings_->GetFullPath(include_dir)));
    }

    static constexpr const char* define_str = "#define ";
    for (std::string define : it.cur().defines()) {
      size_t equal_pos = define.find('=');
      if (equal_pos != std::string::npos)
        define[equal_pos] = ' ';
      define.insert(0, define_str);
      defines_.insert(define);
    }

    CompilerOptions options;
    ParseCompilerOptions(it.cur().cflags(), &options);
    ParseCompilerOptions(it.cur().cflags_c(), &options);
    ParseCompilerOptions(it.cur().cflags_cc(), &options);

    auto add_define_version = [this](auto& ver) {
      if (ver)
        defines_.insert(define_str + ToMacro(*ver));
    };
    add_define_version(options.c_version_);
    add_define_version(options.cxx_version_);
  }
}

void QtCreatorWriter::GenerateFile(const base::FilePath::CharType* suffix,
                                   const std::set<std::string>& items) {
  const base::FilePath file_path = project_prefix_.AddExtension(suffix);
  std::ostringstream output;
  for (const std::string& item : items)
    output << item << std::endl;
  WriteFileIfChanged(file_path, output.str(), &err_);
}

void QtCreatorWriter::Run() {
  if (!DiscoverTargets())
    return;

  for (const Target* target : targets_) {
    if (target->toolchain()->label() !=
        builder_.loader()->GetDefaultToolchain())
      continue;
    HandleTarget(target);
  }

  std::set<std::string> empty_list;

  GenerateFile(kMainProjectFileSuffix, empty_list);
  GenerateFile(kSourcesFileSuffix, sources_);
  GenerateFile(kIncludesFileSuffix, includes_);
  GenerateFile(kDefinesFileSuffix, defines_);
}
