// 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 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 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 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:
      return "DynamicLibrary";
    case Target::STATIC_LIBRARY:
    case Target::SOURCE_SET:
      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;
}

}  // 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;
    default:
      NOTREACHED() << "Not a valid Visual Studio Version: " << version;
  }

  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,
                                          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, 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,
                                           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, &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,
    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::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>(
            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>(
            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;
}
