// 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 "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 "gn/builder.h"
#include "gn/config_values_extractors.h"
#include "gn/deps_iterator.h"
#include "gn/filesystem_utils.h"
#include "gn/label.h"
#include "gn/loader.h"
#include "gn/string_output_buffer.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_ = TargetSet(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 = builder_.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);
  StringOutputBuffer storage;
  std::ostream output(&storage);
  for (const std::string& item : items)
    output << item << std::endl;
  storage.WriteToFileIfChanged(file_path, &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_);
}
