// 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/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.0.17134.0";  // 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));

  std::stringstream vcxproj_string_out;
  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 (!WriteFileIfChanged(vcxproj_path, vcxproj_string_out.str(), err))
    return false;

  base::FilePath filters_path = UTF8ToFilePath(vcxproj_path_str + ".filters");
  std::stringstream filters_string_out;
  WriteFiltersFileContents(filters_string_out, target, source_types);
  return WriteFileIfChanged(filters_path, filters_string_out.str(), 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);

  std::stringstream string_out;
  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 WriteFileIfChanged(sln_path, string_out.str(), 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;
}
