// Copyright 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/visual_studio_writer.h"

#include <algorithm>
#include <iterator>
#include <map>
#include <memory>
#include <set>
#include <string>

#include "base/containers/queue.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "gn/builder.h"
#include "gn/commands.h"
#include "gn/config.h"
#include "gn/config_values_extractors.h"
#include "gn/deps_iterator.h"
#include "gn/filesystem_utils.h"
#include "gn/label_pattern.h"
#include "gn/parse_tree.h"
#include "gn/path_output.h"
#include "gn/standard_out.h"
#include "gn/string_output_buffer.h"
#include "gn/target.h"
#include "gn/variables.h"
#include "gn/visual_studio_utils.h"
#include "gn/xml_element_writer.h"

#if defined(OS_WIN)
#include "base/win/registry.h"
#endif

namespace {

struct SemicolonSeparatedWriter {
  void operator()(const std::string& value, std::ostream& out) const {
    out << XmlEscape(value) + ';';
  }
};

struct IncludeDirWriter {
  explicit IncludeDirWriter(PathOutput& path_output)
      : path_output_(path_output) {}
  ~IncludeDirWriter() = default;

  void operator()(const SourceDir& dir, std::ostream& out) const {
    path_output_.WriteDir(out, dir, PathOutput::DIR_NO_LAST_SLASH);
    out << ";";
  }

  PathOutput& path_output_;
};

struct SourceFileWriter {
  SourceFileWriter(PathOutput& path_output, const SourceFile& source_file)
      : path_output_(path_output), source_file_(source_file) {}
  ~SourceFileWriter() = default;

  void operator()(std::ostream& out) const {
    path_output_.WriteFile(out, source_file_);
  }

  PathOutput& path_output_;
  const SourceFile& source_file_;
};

const char kToolsetVersionVs2013[] = "v120";               // Visual Studio 2013
const char kToolsetVersionVs2015[] = "v140";               // Visual Studio 2015
const char kToolsetVersionVs2017[] = "v141";               // Visual Studio 2017
const char kToolsetVersionVs2019[] = "v142";               // Visual Studio 2019
const char kToolsetVersionVs2022[] = "v143";               // Visual Studio 2022
const char kProjectVersionVs2013[] = "12.0";               // Visual Studio 2013
const char kProjectVersionVs2015[] = "14.0";               // Visual Studio 2015
const char kProjectVersionVs2017[] = "15.0";               // Visual Studio 2017
const char kProjectVersionVs2019[] = "16.0";               // Visual Studio 2019
const char kProjectVersionVs2022[] = "17.0";               // Visual Studio 2022
const char kVersionStringVs2013[] = "Visual Studio 2013";  // Visual Studio 2013
const char kVersionStringVs2015[] = "Visual Studio 2015";  // Visual Studio 2015
const char kVersionStringVs2017[] = "Visual Studio 2017";  // Visual Studio 2017
const char kVersionStringVs2019[] = "Visual Studio 2019";  // Visual Studio 2019
const char kVersionStringVs2022[] = "Visual Studio 2022";  // Visual Studio 2022
const char kWindowsKitsVersion[] = "10";                   // Windows 10 SDK
const char kWindowsKitsDefaultVersion[] = "10";            // Windows 10 SDK

const char kGuidTypeProject[] = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}";
const char kGuidTypeFolder[] = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}";
const char kGuidSeedProject[] = "project";
const char kGuidSeedFolder[] = "folder";
const char kGuidSeedFilter[] = "filter";

const char kConfigurationName[] = "GN";

const char kCharSetUnicode[] = "_UNICODE";
const char kCharSetMultiByte[] = "_MBCS";

std::string GetWindowsKitsIncludeDirs(const std::string& win_kit) {
  std::string kits_path;

#if defined(OS_WIN)
  const char16_t* const subkeys[] = {
      u"SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots",
      u"SOFTWARE\\Wow6432Node\\Microsoft\\Windows Kits\\Installed Roots"};

  std::u16string value_name =
      base::ASCIIToUTF16("KitsRoot") + base::ASCIIToUTF16(kWindowsKitsVersion);

  for (const char16_t* subkey : subkeys) {
    base::win::RegKey key(HKEY_LOCAL_MACHINE, subkey, KEY_READ);
    std::u16string value;
    if (key.ReadValue(value_name.c_str(), &value) == ERROR_SUCCESS) {
      kits_path = base::UTF16ToUTF8(value);
      break;
    }
  }
#endif  // OS_WIN

  if (kits_path.empty()) {
    kits_path = std::string("C:\\Program Files (x86)\\Windows Kits\\") +
                kWindowsKitsVersion + "\\";
  }

  const std::string kit_prefix = kits_path + "Include\\" + win_kit + "\\";
  return kit_prefix + "shared;" + kit_prefix + "um;" + kit_prefix + "winrt;";
}

std::string GetConfigurationType(const Target* target, Err* err) {
  switch (target->output_type()) {
    case Target::EXECUTABLE:
      return "Application";
    case Target::SHARED_LIBRARY:
    case Target::LOADABLE_MODULE:
    case Target::RUST_PROC_MACRO:
      return "DynamicLibrary";
    case Target::STATIC_LIBRARY:
    case Target::SOURCE_SET:
    case Target::RUST_LIBRARY:
      return "StaticLibrary";
    case Target::GROUP:
      return "Utility";

    default:
      *err = Err(Location(),
                 "Visual Studio doesn't support '" + target->label().name() +
                     "' target output type: " +
                     Target::GetStringForOutputType(target->output_type()));
      return std::string();
  }
}

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

void ParseCompilerOptions(const Target* target, CompilerOptions* options) {
  for (ConfigValuesIterator iter(target); !iter.done(); iter.Next()) {
    ParseCompilerOptions(iter.cur().cflags(), options);
    ParseCompilerOptions(iter.cur().cflags_c(), options);
    ParseCompilerOptions(iter.cur().cflags_cc(), options);
  }
}

void ParseLinkerOptions(const std::vector<std::string>& ldflags,
                        LinkerOptions* options) {
  for (const std::string& flag : ldflags)
    ParseLinkerOption(flag, options);
}

void ParseLinkerOptions(const Target* target, LinkerOptions* options) {
  for (ConfigValuesIterator iter(target); !iter.done(); iter.Next()) {
    ParseLinkerOptions(iter.cur().ldflags(), options);
  }
}

// Returns a string piece pointing into the input string identifying the parent
// directory path, excluding the last slash. Note that the input pointer must
// outlive the output.
std::string_view FindParentDir(const std::string* path) {
  DCHECK(path && !path->empty());
  for (int i = static_cast<int>(path->size()) - 2; i >= 0; --i) {
    if (IsSlash((*path)[i]))
      return std::string_view(path->data(), i);
  }
  return std::string_view();
}

bool FilterTargets(const BuildSettings* build_settings,
                   const Builder& builder,
                   const std::string& filters,
                   bool no_deps,
                   std::vector<const Target*>* targets,
                   Err* err) {
  if (filters.empty()) {
    *targets = builder.GetAllResolvedTargets();
    return true;
  }

  std::vector<LabelPattern> patterns;
  if (!commands::FilterPatternsFromString(build_settings, filters, &patterns,
                                          err))
    return false;

  commands::FilterTargetsByPatterns(builder.GetAllResolvedTargets(), patterns,
                                    targets);

  if (no_deps)
    return true;

  std::set<Label> labels;
  base::queue<const Target*> to_process;
  for (const Target* target : *targets) {
    labels.insert(target->label());
    to_process.push(target);
  }

  while (!to_process.empty()) {
    const Target* target = to_process.front();
    to_process.pop();
    for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) {
      if (labels.find(pair.label) == labels.end()) {
        targets->push_back(pair.ptr);
        to_process.push(pair.ptr);
        labels.insert(pair.label);
      }
    }
  }

  return true;
}

bool UnicodeTarget(const Target* target) {
  for (ConfigValuesIterator it(target); !it.done(); it.Next()) {
    for (const std::string& define : it.cur().defines()) {
      if (define == kCharSetUnicode)
        return true;
      if (define == kCharSetMultiByte)
        return false;
    }
  }
  return true;
}

std::string GetNinjaExecutable(const std::string& ninja_executable) {
  return ninja_executable.empty() ? "ninja.exe" : ninja_executable;
}

}  // namespace

VisualStudioWriter::SolutionEntry::SolutionEntry(const std::string& _name,
                                                 const std::string& _path,
                                                 const std::string& _guid)
    : name(_name), path(_path), guid(_guid), parent_folder(nullptr) {}

VisualStudioWriter::SolutionEntry::~SolutionEntry() = default;

VisualStudioWriter::SolutionProject::SolutionProject(
    const std::string& _name,
    const std::string& _path,
    const std::string& _guid,
    const std::string& _label_dir_path,
    const std::string& _config_platform)
    : SolutionEntry(_name, _path, _guid),
      label_dir_path(_label_dir_path),
      config_platform(_config_platform) {
  // Make sure all paths use the same drive letter case. This is especially
  // important when searching for the common path prefix.
  label_dir_path[0] = base::ToUpperASCII(label_dir_path[0]);
}

VisualStudioWriter::SolutionProject::~SolutionProject() = default;

VisualStudioWriter::SourceFileCompileTypePair::SourceFileCompileTypePair(
    const SourceFile* _file,
    const char* _compile_type)
    : file(_file), compile_type(_compile_type) {}

VisualStudioWriter::SourceFileCompileTypePair::~SourceFileCompileTypePair() =
    default;

VisualStudioWriter::VisualStudioWriter(const BuildSettings* build_settings,
                                       const char* config_platform,
                                       Version version,
                                       const std::string& win_kit)
    : build_settings_(build_settings),
      config_platform_(config_platform),
      ninja_path_output_(build_settings->build_dir(),
                         build_settings->root_path_utf8(),
                         EscapingMode::ESCAPE_NINJA_COMMAND),
      windows_sdk_version_(win_kit) {
  DCHECK(!win_kit.empty());

  switch (version) {
    case Version::Vs2013:
      project_version_ = kProjectVersionVs2013;
      toolset_version_ = kToolsetVersionVs2013;
      version_string_ = kVersionStringVs2013;
      break;
    case Version::Vs2015:
      project_version_ = kProjectVersionVs2015;
      toolset_version_ = kToolsetVersionVs2015;
      version_string_ = kVersionStringVs2015;
      break;
    case Version::Vs2017:
      project_version_ = kProjectVersionVs2017;
      toolset_version_ = kToolsetVersionVs2017;
      version_string_ = kVersionStringVs2017;
      break;
    case Version::Vs2019:
      project_version_ = kProjectVersionVs2019;
      toolset_version_ = kToolsetVersionVs2019;
      version_string_ = kVersionStringVs2019;
      break;
    case Version::Vs2022:
      project_version_ = kProjectVersionVs2022;
      toolset_version_ = kToolsetVersionVs2022;
      version_string_ = kVersionStringVs2022;
      break;
  }

  windows_kits_include_dirs_ = GetWindowsKitsIncludeDirs(win_kit);
}

VisualStudioWriter::~VisualStudioWriter() = default;

// static
bool VisualStudioWriter::RunAndWriteFiles(const BuildSettings* build_settings,
                                          const Builder& builder,
                                          Version version,
                                          const std::string& sln_name,
                                          const std::string& filters,
                                          const std::string& win_sdk,
                                          const std::string& ninja_extra_args,
                                          const std::string& ninja_executable,
                                          bool no_deps,
                                          Err* err) {
  std::vector<const Target*> targets;
  if (!FilterTargets(build_settings, builder, filters, no_deps, &targets, err))
    return false;

  std::string win_kit = kWindowsKitsDefaultVersion;
  if (!win_sdk.empty())
    win_kit = win_sdk;

  const char* config_platform = "Win32";

  // Assume the "target_cpu" variable does not change between different
  // toolchains.
  if (!targets.empty()) {
    const Scope* scope = targets.front()->settings()->base_config();
    const Value* target_cpu_value = scope->GetValue(variables::kTargetCpu);
    if (target_cpu_value != nullptr &&
        target_cpu_value->string_value() == "x64")
      config_platform = "x64";
  }

  VisualStudioWriter writer(build_settings, config_platform, version, win_kit);
  writer.projects_.reserve(targets.size());
  writer.folders_.reserve(targets.size());

  for (const Target* target : targets) {
    // Skip actions and bundle targets.
    if (target->output_type() == Target::ACTION ||
        target->output_type() == Target::ACTION_FOREACH ||
        target->output_type() == Target::BUNDLE_DATA ||
        target->output_type() == Target::COPY_FILES ||
        target->output_type() == Target::CREATE_BUNDLE ||
        target->output_type() == Target::GENERATED_FILE) {
      continue;
    }

    if (!writer.WriteProjectFiles(target, ninja_extra_args, ninja_executable,
                                  err))
      return false;
  }

  if (writer.projects_.empty()) {
    *err = Err(Location(), "No Visual Studio projects generated.");
    return false;
  }

  // Sort projects so they appear always in the same order in solution file.
  // Otherwise solution file is rewritten and reloaded by Visual Studio.
  std::sort(writer.projects_.begin(), writer.projects_.end(),
            [](const std::unique_ptr<SolutionProject>& a,
               const std::unique_ptr<SolutionProject>& b) {
              return a->path < b->path;
            });

  writer.ResolveSolutionFolders();
  return writer.WriteSolutionFile(sln_name, err);
}

bool VisualStudioWriter::WriteProjectFiles(const Target* target,
                                           const std::string& ninja_extra_args,
                                           const std::string& ninja_executable,
                                           Err* err) {
  std::string project_name = target->label().name();
  const char* project_config_platform = config_platform_;
  if (!target->settings()->is_default()) {
    project_name += "_" + target->toolchain()->label().name();
    const Value* value =
        target->settings()->base_config()->GetValue(variables::kCurrentCpu);
    if (value != nullptr && value->string_value() == "x64")
      project_config_platform = "x64";
    else
      project_config_platform = "Win32";
  }

  SourceFile target_file =
      GetBuildDirForTargetAsSourceDir(target, BuildDirType::OBJ)
          .ResolveRelativeFile(Value(nullptr, project_name + ".vcxproj"), err);
  if (target_file.is_null())
    return false;

  base::FilePath vcxproj_path = build_settings_->GetFullPath(target_file);
  std::string vcxproj_path_str = FilePathToUTF8(vcxproj_path);

  projects_.push_back(std::make_unique<SolutionProject>(
      project_name, vcxproj_path_str,
      MakeGuid(vcxproj_path_str, kGuidSeedProject),
      FilePathToUTF8(build_settings_->GetFullPath(target->label().dir())),
      project_config_platform));

  StringOutputBuffer vcxproj_storage;
  std::ostream vcxproj_string_out(&vcxproj_storage);
  SourceFileCompileTypePairs source_types;
  if (!WriteProjectFileContents(vcxproj_string_out, *projects_.back(), target,
                                ninja_extra_args, ninja_executable,
                                &source_types, err)) {
    projects_.pop_back();
    return false;
  }

  // Only write the content to the file if it's different. That is
  // both a performance optimization and more importantly, prevents
  // Visual Studio from reloading the projects.
  if (!vcxproj_storage.WriteToFileIfChanged(vcxproj_path, err))
    return false;

  base::FilePath filters_path = UTF8ToFilePath(vcxproj_path_str + ".filters");

  StringOutputBuffer filters_storage;
  std::ostream filters_string_out(&filters_storage);
  WriteFiltersFileContents(filters_string_out, target, source_types);
  return filters_storage.WriteToFileIfChanged(filters_path, err);
}

bool VisualStudioWriter::WriteProjectFileContents(
    std::ostream& out,
    const SolutionProject& solution_project,
    const Target* target,
    const std::string& ninja_extra_args,
    const std::string& ninja_executable,
    SourceFileCompileTypePairs* source_types,
    Err* err) {
  PathOutput path_output(
      GetBuildDirForTargetAsSourceDir(target, BuildDirType::OBJ),
      build_settings_->root_path_utf8(), EscapingMode::ESCAPE_NONE);

  out << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl;
  XmlElementWriter project(
      out, "Project",
      XmlAttributes("DefaultTargets", "Build")
          .add("ToolsVersion", project_version_)
          .add("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"));

  {
    std::unique_ptr<XmlElementWriter> configurations = project.SubElement(
        "ItemGroup", XmlAttributes("Label", "ProjectConfigurations"));
    std::unique_ptr<XmlElementWriter> project_config =
        configurations->SubElement(
            "ProjectConfiguration",
            XmlAttributes("Include", std::string(kConfigurationName) + '|' +
                                         solution_project.config_platform));
    project_config->SubElement("Configuration")->Text(kConfigurationName);
    project_config->SubElement("Platform")
        ->Text(solution_project.config_platform);
  }

  {
    std::unique_ptr<XmlElementWriter> globals =
        project.SubElement("PropertyGroup", XmlAttributes("Label", "Globals"));
    globals->SubElement("ProjectGuid")->Text(solution_project.guid);
    globals->SubElement("Keyword")->Text("Win32Proj");
    globals->SubElement("RootNamespace")->Text(target->label().name());
    globals->SubElement("IgnoreWarnCompileDuplicatedFilename")->Text("true");
    globals->SubElement("PreferredToolArchitecture")->Text("x64");
    globals->SubElement("WindowsTargetPlatformVersion")
        ->Text(windows_sdk_version_);
  }

  project.SubElement(
      "Import", XmlAttributes("Project",
                              "$(VCTargetsPath)\\Microsoft.Cpp.Default.props"));

  {
    std::unique_ptr<XmlElementWriter> configuration = project.SubElement(
        "PropertyGroup", XmlAttributes("Label", "Configuration"));
    bool unicode_target = UnicodeTarget(target);
    configuration->SubElement("CharacterSet")
        ->Text(unicode_target ? "Unicode" : "MultiByte");
    std::string configuration_type = GetConfigurationType(target, err);
    if (configuration_type.empty())
      return false;
    configuration->SubElement("ConfigurationType")->Text(configuration_type);
  }

  {
    std::unique_ptr<XmlElementWriter> locals =
        project.SubElement("PropertyGroup", XmlAttributes("Label", "Locals"));
    locals->SubElement("PlatformToolset")->Text(toolset_version_);
  }

  project.SubElement(
      "Import",
      XmlAttributes("Project", "$(VCTargetsPath)\\Microsoft.Cpp.props"));
  project.SubElement(
      "Import",
      XmlAttributes("Project",
                    "$(VCTargetsPath)\\BuildCustomizations\\masm.props"));
  project.SubElement("ImportGroup",
                     XmlAttributes("Label", "ExtensionSettings"));

  {
    std::unique_ptr<XmlElementWriter> property_sheets = project.SubElement(
        "ImportGroup", XmlAttributes("Label", "PropertySheets"));
    property_sheets->SubElement(
        "Import",
        XmlAttributes(
            "Condition",
            "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')")
            .add("Label", "LocalAppDataPlatform")
            .add("Project",
                 "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props"));
  }

  project.SubElement("PropertyGroup", XmlAttributes("Label", "UserMacros"));

  std::string ninja_target = GetNinjaTarget(target);
  std::string ninja_exe = GetNinjaExecutable(ninja_executable);

  {
    std::unique_ptr<XmlElementWriter> properties =
        project.SubElement("PropertyGroup");
    properties->SubElement("OutDir")->Text("$(SolutionDir)");
    properties->SubElement("TargetName")->Text("$(ProjectName)");
    if (target->output_type() != Target::GROUP) {
      properties->SubElement("TargetPath")->Text("$(OutDir)\\" + ninja_target);
    }
  }

  {
    std::unique_ptr<XmlElementWriter> item_definitions =
        project.SubElement("ItemDefinitionGroup");
    {
      std::unique_ptr<XmlElementWriter> cl_compile =
          item_definitions->SubElement("ClCompile");
      {
        std::unique_ptr<XmlElementWriter> include_dirs =
            cl_compile->SubElement("AdditionalIncludeDirectories");
        RecursiveTargetConfigToStream<SourceDir>(
            kRecursiveWriterSkipDuplicates, target, &ConfigValues::include_dirs,
            IncludeDirWriter(path_output), include_dirs->StartContent(false));
        include_dirs->Text(windows_kits_include_dirs_ +
                           "$(VSInstallDir)\\VC\\atlmfc\\include;" +
                           "%(AdditionalIncludeDirectories)");
      }
      CompilerOptions options;
      ParseCompilerOptions(target, &options);
      if (!options.additional_options.empty()) {
        cl_compile->SubElement("AdditionalOptions")
            ->Text(options.additional_options + "%(AdditionalOptions)");
      }
      if (!options.buffer_security_check.empty()) {
        cl_compile->SubElement("BufferSecurityCheck")
            ->Text(options.buffer_security_check);
      }
      cl_compile->SubElement("CompileAsWinRT")->Text("false");
      cl_compile->SubElement("DebugInformationFormat")->Text("ProgramDatabase");
      if (!options.disable_specific_warnings.empty()) {
        cl_compile->SubElement("DisableSpecificWarnings")
            ->Text(options.disable_specific_warnings +
                   "%(DisableSpecificWarnings)");
      }
      cl_compile->SubElement("ExceptionHandling")->Text("false");
      if (!options.forced_include_files.empty()) {
        cl_compile->SubElement("ForcedIncludeFiles")
            ->Text(options.forced_include_files);
      }
      cl_compile->SubElement("MinimalRebuild")->Text("false");
      if (!options.optimization.empty())
        cl_compile->SubElement("Optimization")->Text(options.optimization);
      cl_compile->SubElement("PrecompiledHeader")->Text("NotUsing");
      {
        std::unique_ptr<XmlElementWriter> preprocessor_definitions =
            cl_compile->SubElement("PreprocessorDefinitions");
        RecursiveTargetConfigToStream<std::string>(
            kRecursiveWriterSkipDuplicates, target, &ConfigValues::defines,
            SemicolonSeparatedWriter(),
            preprocessor_definitions->StartContent(false));
        preprocessor_definitions->Text("%(PreprocessorDefinitions)");
      }
      if (!options.runtime_library.empty())
        cl_compile->SubElement("RuntimeLibrary")->Text(options.runtime_library);
      if (!options.treat_warning_as_error.empty()) {
        cl_compile->SubElement("TreatWarningAsError")
            ->Text(options.treat_warning_as_error);
      }
      if (!options.warning_level.empty())
        cl_compile->SubElement("WarningLevel")->Text(options.warning_level);
    }

    std::unique_ptr<XmlElementWriter> link =
        item_definitions->SubElement("Link");
    {
      LinkerOptions options;
      ParseLinkerOptions(target, &options);
      if (!options.subsystem.empty())
        link->SubElement("SubSystem")->Text(options.subsystem);
    }

    // We don't include resource compilation and other link options as ninja
    // files are used to generate real build.
  }

  {
    std::unique_ptr<XmlElementWriter> group = project.SubElement("ItemGroup");
    std::vector<OutputFile> tool_outputs;  // Prevent reallocation in loop.

    for (const SourceFile& file : target->sources()) {
      const char* compile_type;
      const char* tool_name = Tool::kToolNone;
      if (target->GetOutputFilesForSource(file, &tool_name, &tool_outputs)) {
        compile_type = "CustomBuild";
        std::unique_ptr<XmlElementWriter> build = group->SubElement(
            compile_type, "Include", SourceFileWriter(path_output, file));
        build->SubElement("Command")->Text("call " + ninja_exe +
                                           " -C $(OutDir) " + ninja_extra_args +
                                           " " + tool_outputs[0].value());
        build->SubElement("Outputs")->Text("$(OutDir)" +
                                           tool_outputs[0].value());
      } else {
        compile_type = "None";
        group->SubElement(compile_type, "Include",
                          SourceFileWriter(path_output, file));
      }
      source_types->push_back(SourceFileCompileTypePair(&file, compile_type));
    }
  }

  project.SubElement(
      "Import",
      XmlAttributes("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets"));
  project.SubElement(
      "Import",
      XmlAttributes("Project",
                    "$(VCTargetsPath)\\BuildCustomizations\\masm.targets"));
  project.SubElement("ImportGroup", XmlAttributes("Label", "ExtensionTargets"));

  {
    std::unique_ptr<XmlElementWriter> build =
        project.SubElement("Target", XmlAttributes("Name", "Build"));
    build->SubElement(
        "Exec",
        XmlAttributes("Command", "call " + ninja_exe + " -C $(OutDir) " +
                                     ninja_extra_args + " " + ninja_target));
  }

  {
    std::unique_ptr<XmlElementWriter> clean =
        project.SubElement("Target", XmlAttributes("Name", "Clean"));
    clean->SubElement(
        "Exec",
        XmlAttributes("Command",
                      "call " + ninja_exe + " -C $(OutDir) -tclean " +
                      ninja_target));
  }

  return true;
}

void VisualStudioWriter::WriteFiltersFileContents(
    std::ostream& out,
    const Target* target,
    const SourceFileCompileTypePairs& source_types) {
  out << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl;
  XmlElementWriter project(
      out, "Project",
      XmlAttributes("ToolsVersion", "4.0")
          .add("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"));

  std::ostringstream files_out;

  {
    std::unique_ptr<XmlElementWriter> filters_group =
        project.SubElement("ItemGroup");
    XmlElementWriter files_group(files_out, "ItemGroup", XmlAttributes(), 2);

    // File paths are relative to vcxproj files which are generated to out dirs.
    // Filters tree structure need to reflect source directories and be relative
    // to target file. We need two path outputs then.
    PathOutput file_path_output(
        GetBuildDirForTargetAsSourceDir(target, BuildDirType::OBJ),
        build_settings_->root_path_utf8(), EscapingMode::ESCAPE_NONE);
    PathOutput filter_path_output(target->label().dir(),
                                  build_settings_->root_path_utf8(),
                                  EscapingMode::ESCAPE_NONE);

    std::set<std::string> processed_filters;

    for (const auto& file_and_type : source_types) {
      std::unique_ptr<XmlElementWriter> cl_item = files_group.SubElement(
          file_and_type.compile_type, "Include",
          SourceFileWriter(file_path_output, *file_and_type.file));

      std::ostringstream target_relative_out;
      filter_path_output.WriteFile(target_relative_out, *file_and_type.file);
      std::string target_relative_path = target_relative_out.str();
      ConvertPathToSystem(&target_relative_path);
      std::string_view filter_path = FindParentDir(&target_relative_path);

      if (!filter_path.empty()) {
        std::string filter_path_str(filter_path);
        while (processed_filters.find(filter_path_str) ==
               processed_filters.end()) {
          auto it = processed_filters.insert(filter_path_str).first;
          filters_group
              ->SubElement("Filter", XmlAttributes("Include", filter_path_str))
              ->SubElement("UniqueIdentifier")
              ->Text(MakeGuid(filter_path_str, kGuidSeedFilter));
          filter_path_str = std::string(FindParentDir(&(*it)));
          if (filter_path_str.empty())
            break;
        }
        cl_item->SubElement("Filter")->Text(filter_path);
      }
    }
  }

  project.Text(files_out.str());
}

bool VisualStudioWriter::WriteSolutionFile(const std::string& sln_name,
                                           Err* err) {
  std::string name = sln_name.empty() ? "all" : sln_name;
  SourceFile sln_file = build_settings_->build_dir().ResolveRelativeFile(
      Value(nullptr, name + ".sln"), err);
  if (sln_file.is_null())
    return false;

  base::FilePath sln_path = build_settings_->GetFullPath(sln_file);

  StringOutputBuffer storage;
  std::ostream string_out(&storage);
  WriteSolutionFileContents(string_out, sln_path.DirName());

  // Only write the content to the file if it's different. That is
  // both a performance optimization and more importantly, prevents
  // Visual Studio from reloading the projects.
  return storage.WriteToFileIfChanged(sln_path, err);
}

void VisualStudioWriter::WriteSolutionFileContents(
    std::ostream& out,
    const base::FilePath& solution_dir_path) {
  out << "Microsoft Visual Studio Solution File, Format Version 12.00"
      << std::endl;
  out << "# " << version_string_ << std::endl;

  SourceDir solution_dir(FilePathToUTF8(solution_dir_path));
  for (const std::unique_ptr<SolutionEntry>& folder : folders_) {
    out << "Project(\"" << kGuidTypeFolder << "\") = \"(" << folder->name
        << ")\", \"" << RebasePath(folder->path, solution_dir) << "\", \""
        << folder->guid << "\"" << std::endl;
    out << "EndProject" << std::endl;
  }

  for (const std::unique_ptr<SolutionProject>& project : projects_) {
    out << "Project(\"" << kGuidTypeProject << "\") = \"" << project->name
        << "\", \"" << RebasePath(project->path, solution_dir) << "\", \""
        << project->guid << "\"" << std::endl;
    out << "EndProject" << std::endl;
  }

  out << "Global" << std::endl;

  out << "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"
      << std::endl;
  const std::string config_mode_prefix = std::string(kConfigurationName) + '|';
  const std::string config_mode = config_mode_prefix + config_platform_;
  out << "\t\t" << config_mode << " = " << config_mode << std::endl;
  out << "\tEndGlobalSection" << std::endl;

  out << "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution"
      << std::endl;
  for (const std::unique_ptr<SolutionProject>& project : projects_) {
    const std::string project_config_mode =
        config_mode_prefix + project->config_platform;
    out << "\t\t" << project->guid << '.' << config_mode
        << ".ActiveCfg = " << project_config_mode << std::endl;
    out << "\t\t" << project->guid << '.' << config_mode
        << ".Build.0 = " << project_config_mode << std::endl;
  }
  out << "\tEndGlobalSection" << std::endl;

  out << "\tGlobalSection(SolutionProperties) = preSolution" << std::endl;
  out << "\t\tHideSolutionNode = FALSE" << std::endl;
  out << "\tEndGlobalSection" << std::endl;

  out << "\tGlobalSection(NestedProjects) = preSolution" << std::endl;
  for (const std::unique_ptr<SolutionEntry>& folder : folders_) {
    if (folder->parent_folder) {
      out << "\t\t" << folder->guid << " = " << folder->parent_folder->guid
          << std::endl;
    }
  }
  for (const std::unique_ptr<SolutionProject>& project : projects_) {
    out << "\t\t" << project->guid << " = " << project->parent_folder->guid
        << std::endl;
  }
  out << "\tEndGlobalSection" << std::endl;

  out << "EndGlobal" << std::endl;
}

void VisualStudioWriter::ResolveSolutionFolders() {
  root_folder_path_.clear();

  // Get all project directories. Create solution folder for each directory.
  std::map<std::string_view, SolutionEntry*> processed_paths;
  for (const std::unique_ptr<SolutionProject>& project : projects_) {
    std::string_view folder_path = project->label_dir_path;
    if (IsSlash(folder_path[folder_path.size() - 1]))
      folder_path = folder_path.substr(0, folder_path.size() - 1);
    auto it = processed_paths.find(folder_path);
    if (it != processed_paths.end()) {
      project->parent_folder = it->second;
    } else {
      std::string folder_path_str(folder_path);
      std::unique_ptr<SolutionEntry> folder = std::make_unique<SolutionEntry>(
          std::string(
              FindLastDirComponent(SourceDir(std::string(folder_path)))),
          folder_path_str, MakeGuid(folder_path_str, kGuidSeedFolder));
      project->parent_folder = folder.get();
      processed_paths[folder_path] = folder.get();
      folders_.push_back(std::move(folder));

      if (root_folder_path_.empty()) {
        root_folder_path_ = folder_path_str;
      } else {
        size_t common_prefix_len = 0;
        size_t max_common_length =
            std::min(root_folder_path_.size(), folder_path.size());
        size_t i;
        for (i = common_prefix_len; i < max_common_length; ++i) {
          if (IsSlash(root_folder_path_[i]) && IsSlash(folder_path[i]))
            common_prefix_len = i + 1;
          else if (root_folder_path_[i] != folder_path[i])
            break;
        }
        if (i == max_common_length &&
            (i == folder_path.size() || IsSlash(folder_path[i])))
          common_prefix_len = max_common_length;
        if (common_prefix_len < root_folder_path_.size()) {
          if (IsSlash(root_folder_path_[common_prefix_len - 1]))
            --common_prefix_len;
          root_folder_path_ = root_folder_path_.substr(0, common_prefix_len);
        }
      }
    }
  }

  // Create also all parent folders up to |root_folder_path_|.
  SolutionFolders additional_folders;
  for (const std::unique_ptr<SolutionEntry>& solution_folder : folders_) {
    if (solution_folder->path == root_folder_path_)
      continue;

    SolutionEntry* folder = solution_folder.get();
    std::string_view parent_path;
    while ((parent_path = FindParentDir(&folder->path)) != root_folder_path_) {
      auto it = processed_paths.find(parent_path);
      if (it != processed_paths.end()) {
        folder = it->second;
      } else {
        std::unique_ptr<SolutionEntry> new_folder =
            std::make_unique<SolutionEntry>(
                std::string(
                    FindLastDirComponent(SourceDir(std::string(parent_path)))),
                std::string(parent_path),
                MakeGuid(std::string(parent_path), kGuidSeedFolder));
        processed_paths[parent_path] = new_folder.get();
        folder = new_folder.get();
        additional_folders.push_back(std::move(new_folder));
      }
    }
  }
  folders_.insert(folders_.end(),
                  std::make_move_iterator(additional_folders.begin()),
                  std::make_move_iterator(additional_folders.end()));

  // Sort folders by path.
  std::sort(folders_.begin(), folders_.end(),
            [](const std::unique_ptr<SolutionEntry>& a,
               const std::unique_ptr<SolutionEntry>& b) {
              return a->path < b->path;
            });

  // Match subfolders with their parents. Since |folders_| are sorted by path we
  // know that parent folder always precedes its children in vector.
  std::vector<SolutionEntry*> parents;
  for (const std::unique_ptr<SolutionEntry>& folder : folders_) {
    while (!parents.empty()) {
      if (base::StartsWith(folder->path, parents.back()->path,
                           base::CompareCase::SENSITIVE)) {
        folder->parent_folder = parents.back();
        break;
      } else {
        parents.pop_back();
      }
    }
    parents.push_back(folder.get());
  }
}

std::string VisualStudioWriter::GetNinjaTarget(const Target* target) {
  std::ostringstream ninja_target_out;
  DCHECK(!target->dependency_output_file().value().empty());
  ninja_path_output_.WriteFile(ninja_target_out,
                               target->dependency_output_file());
  std::string s = ninja_target_out.str();
  if (s.compare(0, 2, "./") == 0)
    s = s.substr(2);
  return s;
}
