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

#include <iomanip>
#include <iterator>
#include <memory>
#include <sstream>
#include <utility>

#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string_util.h"
#include "gn/filesystem_utils.h"

// Helper methods -------------------------------------------------------------

namespace {
struct IndentRules {
  bool one_line;
  unsigned level;
};

std::vector<std::unique_ptr<PBXObject>> EmptyPBXObjectVector() {
  return std::vector<std::unique_ptr<PBXObject>>();
}

bool CharNeedEscaping(char c) {
  if (base::IsAsciiAlpha(c) || base::IsAsciiDigit(c))
    return false;
  if (c == '$' || c == '.' || c == '/' || c == '_')
    return false;
  return true;
}

bool StringNeedEscaping(const std::string& string) {
  if (string.empty())
    return true;
  if (string.find("___") != std::string::npos)
    return true;

  for (char c : string) {
    if (CharNeedEscaping(c))
      return true;
  }
  return false;
}

std::string EncodeString(const std::string& string) {
  if (!StringNeedEscaping(string))
    return string;

  std::stringstream buffer;
  buffer << '"';
  for (char c : string) {
    if (c <= 31) {
      switch (c) {
        case '\a':
          buffer << "\\a";
          break;
        case '\b':
          buffer << "\\b";
          break;
        case '\t':
          buffer << "\\t";
          break;
        case '\n':
        case '\r':
          buffer << "\\n";
          break;
        case '\v':
          buffer << "\\v";
          break;
        case '\f':
          buffer << "\\f";
          break;
        default:
          buffer << std::hex << std::setw(4) << std::left << "\\U"
                 << static_cast<unsigned>(c);
          break;
      }
    } else {
      if (c == '"' || c == '\\')
        buffer << '\\';
      buffer << c;
    }
  }
  buffer << '"';
  return buffer.str();
}

struct SourceTypeForExt {
  const char* ext;
  const char* source_type;
};

const SourceTypeForExt kSourceTypeForExt[] = {
    {"a", "archive.ar"},
    {"app", "wrapper.application"},
    {"appex", "wrapper.app-extension"},
    {"bdic", "file"},
    {"bundle", "wrapper.cfbundle"},
    {"c", "sourcecode.c.c"},
    {"cc", "sourcecode.cpp.cpp"},
    {"cpp", "sourcecode.cpp.cpp"},
    {"css", "text.css"},
    {"cxx", "sourcecode.cpp.cpp"},
    {"dart", "sourcecode"},
    {"dylib", "compiled.mach-o.dylib"},
    {"framework", "wrapper.framework"},
    {"h", "sourcecode.c.h"},
    {"hxx", "sourcecode.cpp.h"},
    {"icns", "image.icns"},
    {"java", "sourcecode.java"},
    {"js", "sourcecode.javascript"},
    {"kext", "wrapper.kext"},
    {"m", "sourcecode.c.objc"},
    {"mm", "sourcecode.cpp.objcpp"},
    {"nib", "wrapper.nib"},
    {"o", "compiled.mach-o.objfile"},
    {"pdf", "image.pdf"},
    {"pl", "text.script.perl"},
    {"plist", "text.plist.xml"},
    {"pm", "text.script.perl"},
    {"png", "image.png"},
    {"py", "text.script.python"},
    {"r", "sourcecode.rez"},
    {"rez", "sourcecode.rez"},
    {"s", "sourcecode.asm"},
    {"storyboard", "file.storyboard"},
    {"strings", "text.plist.strings"},
    {"swift", "sourcecode.swift"},
    {"ttf", "file"},
    {"xcassets", "folder.assetcatalog"},
    {"xcconfig", "text.xcconfig"},
    {"xcdatamodel", "wrapper.xcdatamodel"},
    {"xcdatamodeld", "wrapper.xcdatamodeld"},
    {"xib", "file.xib"},
    {"y", "sourcecode.yacc"},
};

const char* GetSourceType(const std::string_view& ext) {
  for (size_t i = 0; i < std::size(kSourceTypeForExt); ++i) {
    if (kSourceTypeForExt[i].ext == ext)
      return kSourceTypeForExt[i].source_type;
  }

  return "text";
}

bool HasExplicitFileType(const std::string_view& ext) {
  return ext == "dart";
}

bool IsSourceFileForIndexing(const std::string_view& ext) {
  return ext == "c" || ext == "cc" || ext == "cpp" || ext == "cxx" ||
         ext == "m" || ext == "mm";
}

void PrintValue(std::ostream& out, IndentRules rules, unsigned value) {
  out << value;
}

void PrintValue(std::ostream& out, IndentRules rules, const char* value) {
  out << EncodeString(value);
}

void PrintValue(std::ostream& out,
                IndentRules rules,
                const std::string& value) {
  out << EncodeString(value);
}

void PrintValue(std::ostream& out, IndentRules rules, const PBXObject* value) {
  out << value->Reference();
}

template <typename ObjectClass>
void PrintValue(std::ostream& out,
                IndentRules rules,
                const std::unique_ptr<ObjectClass>& value) {
  PrintValue(out, rules, value.get());
}

template <typename ValueType>
void PrintValue(std::ostream& out,
                IndentRules rules,
                const std::vector<ValueType>& values) {
  IndentRules sub_rule{rules.one_line, rules.level + 1};
  out << "(" << (rules.one_line ? " " : "\n");
  for (const auto& value : values) {
    if (!sub_rule.one_line)
      out << std::string(sub_rule.level, '\t');

    PrintValue(out, sub_rule, value);
    out << "," << (rules.one_line ? " " : "\n");
  }

  if (!rules.one_line && rules.level)
    out << std::string(rules.level, '\t');
  out << ")";
}

template <typename ValueType>
void PrintValue(std::ostream& out,
                IndentRules rules,
                const std::map<std::string, ValueType>& values) {
  IndentRules sub_rule{rules.one_line, rules.level + 1};
  out << "{" << (rules.one_line ? " " : "\n");
  for (const auto& pair : values) {
    if (!sub_rule.one_line)
      out << std::string(sub_rule.level, '\t');

    out << pair.first << " = ";
    PrintValue(out, sub_rule, pair.second);
    out << ";" << (rules.one_line ? " " : "\n");
  }

  if (!rules.one_line && rules.level)
    out << std::string(rules.level, '\t');
  out << "}";
}

template <typename ValueType>
void PrintProperty(std::ostream& out,
                   IndentRules rules,
                   const char* name,
                   ValueType&& value) {
  if (!rules.one_line && rules.level)
    out << std::string(rules.level, '\t');

  out << name << " = ";
  PrintValue(out, rules, std::forward<ValueType>(value));
  out << ";" << (rules.one_line ? " " : "\n");
}

struct PBXGroupComparator {
  using PBXObjectPtr = std::unique_ptr<PBXObject>;
  bool operator()(const PBXObjectPtr& lhs, const PBXObjectPtr& rhs) {
    if (lhs->Class() != rhs->Class())
      return rhs->Class() < lhs->Class();

    if (lhs->Class() == PBXGroupClass) {
      PBXGroup* lhs_group = static_cast<PBXGroup*>(lhs.get());
      PBXGroup* rhs_group = static_cast<PBXGroup*>(rhs.get());
      return lhs_group->name() < rhs_group->name();
    }

    DCHECK_EQ(lhs->Class(), PBXFileReferenceClass);
    PBXFileReference* lhs_file = static_cast<PBXFileReference*>(lhs.get());
    PBXFileReference* rhs_file = static_cast<PBXFileReference*>(rhs.get());
    return lhs_file->Name() < rhs_file->Name();
  }
};
}  // namespace

// PBXObjectClass -------------------------------------------------------------

const char* ToString(PBXObjectClass cls) {
  switch (cls) {
    case PBXAggregateTargetClass:
      return "PBXAggregateTarget";
    case PBXBuildFileClass:
      return "PBXBuildFile";
    case PBXContainerItemProxyClass:
      return "PBXContainerItemProxy";
    case PBXFileReferenceClass:
      return "PBXFileReference";
    case PBXFrameworksBuildPhaseClass:
      return "PBXFrameworksBuildPhase";
    case PBXGroupClass:
      return "PBXGroup";
    case PBXNativeTargetClass:
      return "PBXNativeTarget";
    case PBXProjectClass:
      return "PBXProject";
    case PBXShellScriptBuildPhaseClass:
      return "PBXShellScriptBuildPhase";
    case PBXSourcesBuildPhaseClass:
      return "PBXSourcesBuildPhase";
    case PBXTargetDependencyClass:
      return "PBXTargetDependency";
    case XCBuildConfigurationClass:
      return "XCBuildConfiguration";
    case XCConfigurationListClass:
      return "XCConfigurationList";
  }
  NOTREACHED();
  return nullptr;
}

// PBXObjectVisitor -----------------------------------------------------------

PBXObjectVisitor::PBXObjectVisitor() = default;

PBXObjectVisitor::~PBXObjectVisitor() = default;

// PBXObjectVisitorConst ------------------------------------------------------

PBXObjectVisitorConst::PBXObjectVisitorConst() = default;

PBXObjectVisitorConst::~PBXObjectVisitorConst() = default;

// PBXObject ------------------------------------------------------------------

PBXObject::PBXObject() = default;

PBXObject::~PBXObject() = default;

void PBXObject::SetId(const std::string& id) {
  DCHECK(id_.empty());
  DCHECK(!id.empty());
  id_.assign(id);
}

std::string PBXObject::Reference() const {
  std::string comment = Comment();
  if (comment.empty())
    return id_;

  return id_ + " /* " + comment + " */";
}

std::string PBXObject::Comment() const {
  return Name();
}

void PBXObject::Visit(PBXObjectVisitor& visitor) {
  visitor.Visit(this);
}

void PBXObject::Visit(PBXObjectVisitorConst& visitor) const {
  visitor.Visit(this);
}

// PBXBuildPhase --------------------------------------------------------------

PBXBuildPhase::PBXBuildPhase() = default;

PBXBuildPhase::~PBXBuildPhase() = default;

// PBXTarget ------------------------------------------------------------------

PBXTarget::PBXTarget(const std::string& name,
                     const std::string& shell_script,
                     const std::string& config_name,
                     const PBXAttributes& attributes)
    : configurations_(new XCConfigurationList(config_name, attributes, this)),
      name_(name) {
  if (!shell_script.empty()) {
    build_phases_.push_back(
        std::make_unique<PBXShellScriptBuildPhase>(name, shell_script));
  }
}

PBXTarget::~PBXTarget() = default;

void PBXTarget::AddDependency(std::unique_ptr<PBXTargetDependency> dependency) {
  DCHECK(dependency);
  dependencies_.push_back(std::move(dependency));
}

std::string PBXTarget::Name() const {
  return name_;
}

void PBXTarget::Visit(PBXObjectVisitor& visitor) {
  PBXObject::Visit(visitor);
  configurations_->Visit(visitor);
  for (const auto& dependency : dependencies_)
    dependency->Visit(visitor);
  for (const auto& build_phase : build_phases_)
    build_phase->Visit(visitor);
}

void PBXTarget::Visit(PBXObjectVisitorConst& visitor) const {
  PBXObject::Visit(visitor);
  configurations_->Visit(visitor);
  for (const auto& dependency : dependencies_)
    dependency->Visit(visitor);
  for (const auto& build_phase : build_phases_)
    build_phase->Visit(visitor);
}

// PBXAggregateTarget ---------------------------------------------------------

PBXAggregateTarget::PBXAggregateTarget(const std::string& name,
                                       const std::string& shell_script,
                                       const std::string& config_name,
                                       const PBXAttributes& attributes)
    : PBXTarget(name, shell_script, config_name, attributes) {}

PBXAggregateTarget::~PBXAggregateTarget() = default;

PBXObjectClass PBXAggregateTarget::Class() const {
  return PBXAggregateTargetClass;
}

void PBXAggregateTarget::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {false, indent + 1};
  out << indent_str << Reference() << " = {\n";
  PrintProperty(out, rules, "isa", ToString(Class()));
  PrintProperty(out, rules, "buildConfigurationList", configurations_);
  PrintProperty(out, rules, "buildPhases", build_phases_);
  PrintProperty(out, rules, "dependencies", EmptyPBXObjectVector());
  PrintProperty(out, rules, "name", name_);
  PrintProperty(out, rules, "productName", name_);
  out << indent_str << "};\n";
}

// PBXBuildFile ---------------------------------------------------------------

PBXBuildFile::PBXBuildFile(const PBXFileReference* file_reference,
                           const PBXSourcesBuildPhase* build_phase,
                           const CompilerFlags compiler_flag)
    : file_reference_(file_reference),
      build_phase_(build_phase),
      compiler_flag_(compiler_flag) {
  DCHECK(file_reference_);
  DCHECK(build_phase_);
}

PBXBuildFile::~PBXBuildFile() = default;

PBXObjectClass PBXBuildFile::Class() const {
  return PBXBuildFileClass;
}

std::string PBXBuildFile::Name() const {
  return file_reference_->Name() + " in " + build_phase_->Name();
}

void PBXBuildFile::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {true, 0};
  out << indent_str << Reference() << " = {";
  PrintProperty(out, rules, "isa", ToString(Class()));
  PrintProperty(out, rules, "fileRef", file_reference_);
  if (compiler_flag_ == CompilerFlags::HELP) {
    std::map<std::string, std::string> settings = {
        {"COMPILER_FLAGS", "--help"},
    };
    PrintProperty(out, rules, "settings", settings);
  }
  out << "};\n";
}

// PBXContainerItemProxy ------------------------------------------------------
PBXContainerItemProxy::PBXContainerItemProxy(const PBXProject* project,
                                             const PBXTarget* target)
    : project_(project), target_(target) {}

PBXContainerItemProxy::~PBXContainerItemProxy() = default;

PBXObjectClass PBXContainerItemProxy::Class() const {
  return PBXContainerItemProxyClass;
}

std::string PBXContainerItemProxy::Name() const {
  return "PBXContainerItemProxy";
}

void PBXContainerItemProxy::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {true, 0};
  out << indent_str << Reference() << " = {";
  PrintProperty(out, rules, "isa", ToString(Class()));
  PrintProperty(out, rules, "containerPortal", project_);
  PrintProperty(out, rules, "proxyType", 1u);
  PrintProperty(out, rules, "remoteGlobalIDString", target_);
  PrintProperty(out, rules, "remoteInfo", target_->Name());
  out << indent_str << "};\n";
}

// PBXFileReference -----------------------------------------------------------

PBXFileReference::PBXFileReference(const std::string& name,
                                   const std::string& path,
                                   const std::string& type)
    : name_(name), path_(path), type_(type) {}

PBXFileReference::~PBXFileReference() = default;

PBXObjectClass PBXFileReference::Class() const {
  return PBXFileReferenceClass;
}

std::string PBXFileReference::Name() const {
  return name_;
}

void PBXFileReference::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {true, 0};
  out << indent_str << Reference() << " = {";
  PrintProperty(out, rules, "isa", ToString(Class()));

  if (!type_.empty()) {
    PrintProperty(out, rules, "explicitFileType", type_);
    PrintProperty(out, rules, "includeInIndex", 0u);
  } else {
    std::string_view ext = FindExtension(&name_);
    if (HasExplicitFileType(ext))
      PrintProperty(out, rules, "explicitFileType", GetSourceType(ext));
    else
      PrintProperty(out, rules, "lastKnownFileType", GetSourceType(ext));
  }

  if (!name_.empty())
    PrintProperty(out, rules, "name", name_);

  DCHECK(!path_.empty());
  PrintProperty(out, rules, "path", path_);
  PrintProperty(out, rules, "sourceTree",
                type_.empty() ? "<group>" : "BUILT_PRODUCTS_DIR");
  out << "};\n";
}

// PBXFrameworksBuildPhase ----------------------------------------------------

PBXFrameworksBuildPhase::PBXFrameworksBuildPhase() = default;

PBXFrameworksBuildPhase::~PBXFrameworksBuildPhase() = default;

PBXObjectClass PBXFrameworksBuildPhase::Class() const {
  return PBXFrameworksBuildPhaseClass;
}

std::string PBXFrameworksBuildPhase::Name() const {
  return "Frameworks";
}

void PBXFrameworksBuildPhase::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {false, indent + 1};
  out << indent_str << Reference() << " = {\n";
  PrintProperty(out, rules, "isa", ToString(Class()));
  PrintProperty(out, rules, "buildActionMask", 0x7fffffffu);
  PrintProperty(out, rules, "files", EmptyPBXObjectVector());
  PrintProperty(out, rules, "runOnlyForDeploymentPostprocessing", 0u);
  out << indent_str << "};\n";
}

// PBXGroup -------------------------------------------------------------------

PBXGroup::PBXGroup(const std::string& path, const std::string& name)
    : name_(name), path_(path) {}

PBXGroup::~PBXGroup() = default;

PBXFileReference* PBXGroup::AddSourceFile(const std::string& navigator_path,
                                          const std::string& source_path) {
  DCHECK(!navigator_path.empty());
  DCHECK(!source_path.empty());
  std::string::size_type sep = navigator_path.find("/");
  if (sep == std::string::npos) {
    // Prevent same file reference being created and added multiple times.
    for (const auto& child : children_) {
      if (child->Class() != PBXFileReferenceClass)
        continue;

      PBXFileReference* child_as_file_reference =
          static_cast<PBXFileReference*>(child.get());
      if (child_as_file_reference->Name() == navigator_path &&
          child_as_file_reference->path() == source_path) {
        return child_as_file_reference;
      }
    }

    return CreateChild<PBXFileReference>(navigator_path, source_path,
                                         std::string());
  }

  PBXGroup* group = nullptr;
  std::string_view component(navigator_path.data(), sep);
  for (const auto& child : children_) {
    if (child->Class() != PBXGroupClass)
      continue;

    PBXGroup* child_as_group = static_cast<PBXGroup*>(child.get());
    if (child_as_group->name_ == component) {
      group = child_as_group;
      break;
    }
  }

  if (!group) {
    group =
        CreateChild<PBXGroup>(std::string(component), std::string(component));
  }

  DCHECK(group);
  DCHECK(group->name_ == component);
  return group->AddSourceFile(navigator_path.substr(sep + 1), source_path);
}

PBXObjectClass PBXGroup::Class() const {
  return PBXGroupClass;
}

std::string PBXGroup::Name() const {
  if (!name_.empty())
    return name_;
  if (!path_.empty())
    return path_;
  return std::string();
}

void PBXGroup::Visit(PBXObjectVisitor& visitor) {
  PBXObject::Visit(visitor);
  for (const auto& child : children_) {
    child->Visit(visitor);
  }
}

void PBXGroup::Visit(PBXObjectVisitorConst& visitor) const {
  PBXObject::Visit(visitor);
  for (const auto& child : children_) {
    child->Visit(visitor);
  }
}

void PBXGroup::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {false, indent + 1};
  out << indent_str << Reference() << " = {\n";
  PrintProperty(out, rules, "isa", ToString(Class()));
  PrintProperty(out, rules, "children", children_);
  if (!name_.empty())
    PrintProperty(out, rules, "name", name_);
  if (is_source_ && !path_.empty())
    PrintProperty(out, rules, "path", path_);
  PrintProperty(out, rules, "sourceTree", "<group>");
  out << indent_str << "};\n";
}

PBXObject* PBXGroup::AddChildImpl(std::unique_ptr<PBXObject> child) {
  DCHECK(child);
  DCHECK(child->Class() == PBXGroupClass ||
         child->Class() == PBXFileReferenceClass);

  PBXObject* child_ptr = child.get();
  if (autosorted()) {
    auto iter = std::lower_bound(children_.begin(), children_.end(), child,
                                 PBXGroupComparator());
    children_.insert(iter, std::move(child));
  } else {
    children_.push_back(std::move(child));
  }
  return child_ptr;
}

// PBXNativeTarget ------------------------------------------------------------

PBXNativeTarget::PBXNativeTarget(const std::string& name,
                                 const std::string& shell_script,
                                 const std::string& config_name,
                                 const PBXAttributes& attributes,
                                 const std::string& product_type,
                                 const std::string& product_name,
                                 const PBXFileReference* product_reference)
    : PBXTarget(name, shell_script, config_name, attributes),
      product_reference_(product_reference),
      product_type_(product_type),
      product_name_(product_name) {
  DCHECK(product_reference_);
  build_phases_.push_back(std::make_unique<PBXSourcesBuildPhase>());
  source_build_phase_ =
      static_cast<PBXSourcesBuildPhase*>(build_phases_.back().get());

  build_phases_.push_back(std::make_unique<PBXFrameworksBuildPhase>());
}

PBXNativeTarget::~PBXNativeTarget() = default;

void PBXNativeTarget::AddFileForIndexing(const PBXFileReference* file_reference,
                                         const CompilerFlags compiler_flag) {
  DCHECK(file_reference);
  source_build_phase_->AddBuildFile(std::make_unique<PBXBuildFile>(
      file_reference, source_build_phase_, compiler_flag));
}

PBXObjectClass PBXNativeTarget::Class() const {
  return PBXNativeTargetClass;
}

void PBXNativeTarget::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {false, indent + 1};
  out << indent_str << Reference() << " = {\n";
  PrintProperty(out, rules, "isa", ToString(Class()));
  PrintProperty(out, rules, "buildConfigurationList", configurations_);
  PrintProperty(out, rules, "buildPhases", build_phases_);
  PrintProperty(out, rules, "buildRules", EmptyPBXObjectVector());
  PrintProperty(out, rules, "dependencies", dependencies_);
  PrintProperty(out, rules, "name", name_);
  PrintProperty(out, rules, "productName", product_name_);
  PrintProperty(out, rules, "productReference", product_reference_);
  PrintProperty(out, rules, "productType", product_type_);
  out << indent_str << "};\n";
}

// PBXProject -----------------------------------------------------------------

PBXProject::PBXProject(const std::string& name,
                       const std::string& config_name,
                       const std::string& source_path,
                       const PBXAttributes& attributes)
    : name_(name), config_name_(config_name), target_for_indexing_(nullptr) {
  attributes_["BuildIndependentTargetsInParallel"] = "YES";

  main_group_.reset(new PBXGroup);
  main_group_->set_autosorted(false);

  sources_ = main_group_->CreateChild<PBXGroup>(source_path, "Source");
  sources_->set_is_source(true);

  products_ = main_group_->CreateChild<PBXGroup>(std::string(), "Products");

  configurations_.reset(new XCConfigurationList(config_name, attributes, this));
}

PBXProject::~PBXProject() = default;

void PBXProject::AddSourceFileToIndexingTarget(
    const std::string& navigator_path,
    const std::string& source_path,
    const CompilerFlags compiler_flag) {
  if (!target_for_indexing_) {
    AddIndexingTarget();
  }
  AddSourceFile(navigator_path, source_path, compiler_flag,
                target_for_indexing_);
}

void PBXProject::AddSourceFile(const std::string& navigator_path,
                               const std::string& source_path,
                               const CompilerFlags compiler_flag,
                               PBXNativeTarget* target) {
  PBXFileReference* file_reference =
      sources_->AddSourceFile(navigator_path, source_path);
  std::string_view ext = FindExtension(&source_path);
  if (!IsSourceFileForIndexing(ext))
    return;

  DCHECK(target);
  target->AddFileForIndexing(file_reference, compiler_flag);
}

void PBXProject::AddAggregateTarget(const std::string& name,
                                    const std::string& shell_script) {
  PBXAttributes attributes;
  attributes["CODE_SIGNING_REQUIRED"] = "NO";
  attributes["CONFIGURATION_BUILD_DIR"] = ".";
  attributes["PRODUCT_NAME"] = name;

  targets_.push_back(std::make_unique<PBXAggregateTarget>(
      name, shell_script, config_name_, attributes));
}

void PBXProject::AddIndexingTarget() {
  DCHECK(!target_for_indexing_);
  PBXAttributes attributes;
  attributes["EXECUTABLE_PREFIX"] = "";
  attributes["HEADER_SEARCH_PATHS"] = sources_->path();
  attributes["PRODUCT_NAME"] = "sources";

  PBXFileReference* product_reference =
      products_->CreateChild<PBXFileReference>(std::string(), "sources",
                                               "compiled.mach-o.executable");

  const char product_type[] = "com.apple.product-type.tool";
  targets_.push_back(std::make_unique<PBXNativeTarget>(
      "sources", std::string(), config_name_, attributes, product_type,
      "sources", product_reference));
  target_for_indexing_ = static_cast<PBXNativeTarget*>(targets_.back().get());
}

PBXNativeTarget* PBXProject::AddNativeTarget(
    const std::string& name,
    const std::string& type,
    const std::string& output_name,
    const std::string& output_type,
    const std::string& shell_script,
    const PBXAttributes& extra_attributes) {
  std::string_view ext = FindExtension(&output_name);
  PBXFileReference* product = products_->CreateChild<PBXFileReference>(
      std::string(), output_name, type.empty() ? GetSourceType(ext) : type);

  // Per Xcode build settings documentation: Product Name (PRODUCT_NAME) should
  // the basename of the product generated by the target.
  // Therefore, take the basename of output name without file extension as the
  // "PRODUCT_NAME".
  size_t basename_offset = FindFilenameOffset(output_name);
  std::string output_basename = basename_offset != std::string::npos
                                    ? output_name.substr(basename_offset)
                                    : output_name;
  size_t ext_offset = FindExtensionOffset(output_basename);
  std::string product_name = ext_offset != std::string::npos
                                 ? output_basename.substr(0, ext_offset - 1)
                                 : output_basename;

  PBXAttributes attributes = extra_attributes;
  attributes["CODE_SIGNING_REQUIRED"] = "NO";
  attributes["CONFIGURATION_BUILD_DIR"] = ".";
  attributes["PRODUCT_NAME"] = product_name;

  targets_.push_back(std::make_unique<PBXNativeTarget>(
      name, shell_script, config_name_, attributes, output_type, product_name,
      product));
  return static_cast<PBXNativeTarget*>(targets_.back().get());
}

void PBXProject::SetProjectDirPath(const std::string& project_dir_path) {
  DCHECK(!project_dir_path.empty());
  project_dir_path_.assign(project_dir_path);
}

void PBXProject::SetProjectRoot(const std::string& project_root) {
  DCHECK(!project_root.empty());
  project_root_.assign(project_root);
}

void PBXProject::AddTarget(std::unique_ptr<PBXTarget> target) {
  DCHECK(target);
  targets_.push_back(std::move(target));
}

PBXObjectClass PBXProject::Class() const {
  return PBXProjectClass;
}

std::string PBXProject::Name() const {
  return name_;
}

std::string PBXProject::Comment() const {
  return "Project object";
}

void PBXProject::Visit(PBXObjectVisitor& visitor) {
  PBXObject::Visit(visitor);
  configurations_->Visit(visitor);
  main_group_->Visit(visitor);
  for (const auto& target : targets_) {
    target->Visit(visitor);
  }
}

void PBXProject::Visit(PBXObjectVisitorConst& visitor) const {
  PBXObject::Visit(visitor);
  configurations_->Visit(visitor);
  main_group_->Visit(visitor);
  for (const auto& target : targets_) {
    target->Visit(visitor);
  }
}
void PBXProject::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {false, indent + 1};
  out << indent_str << Reference() << " = {\n";
  PrintProperty(out, rules, "isa", ToString(Class()));
  PrintProperty(out, rules, "attributes", attributes_);
  PrintProperty(out, rules, "buildConfigurationList", configurations_);
  PrintProperty(out, rules, "compatibilityVersion", "Xcode 3.2");
  PrintProperty(out, rules, "developmentRegion", "English");
  PrintProperty(out, rules, "hasScannedForEncodings", 1u);
  PrintProperty(out, rules, "knownRegions", std::vector<std::string>({"en"}));
  PrintProperty(out, rules, "mainGroup", main_group_);
  PrintProperty(out, rules, "projectDirPath", project_dir_path_);
  PrintProperty(out, rules, "projectRoot", project_root_);
  PrintProperty(out, rules, "targets", targets_);
  out << indent_str << "};\n";
}

// PBXShellScriptBuildPhase ---------------------------------------------------

PBXShellScriptBuildPhase::PBXShellScriptBuildPhase(
    const std::string& name,
    const std::string& shell_script)
    : name_("Action \"Compile and copy " + name + " via ninja\""),
      shell_script_(shell_script) {}

PBXShellScriptBuildPhase::~PBXShellScriptBuildPhase() = default;

PBXObjectClass PBXShellScriptBuildPhase::Class() const {
  return PBXShellScriptBuildPhaseClass;
}

std::string PBXShellScriptBuildPhase::Name() const {
  return name_;
}

void PBXShellScriptBuildPhase::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {false, indent + 1};
  out << indent_str << Reference() << " = {\n";
  PrintProperty(out, rules, "isa", ToString(Class()));
  PrintProperty(out, rules, "buildActionMask", 0x7fffffffu);
  PrintProperty(out, rules, "files", EmptyPBXObjectVector());
  PrintProperty(out, rules, "inputPaths", EmptyPBXObjectVector());
  PrintProperty(out, rules, "name", name_);
  PrintProperty(out, rules, "outputPaths", EmptyPBXObjectVector());
  PrintProperty(out, rules, "runOnlyForDeploymentPostprocessing", 0u);
  PrintProperty(out, rules, "shellPath", "/bin/sh");
  PrintProperty(out, rules, "shellScript", shell_script_);
  PrintProperty(out, rules, "showEnvVarsInLog", 0u);
  out << indent_str << "};\n";
}

// PBXSourcesBuildPhase -------------------------------------------------------

PBXSourcesBuildPhase::PBXSourcesBuildPhase() = default;

PBXSourcesBuildPhase::~PBXSourcesBuildPhase() = default;

void PBXSourcesBuildPhase::AddBuildFile(
    std::unique_ptr<PBXBuildFile> build_file) {
  files_.push_back(std::move(build_file));
}

PBXObjectClass PBXSourcesBuildPhase::Class() const {
  return PBXSourcesBuildPhaseClass;
}

std::string PBXSourcesBuildPhase::Name() const {
  return "Sources";
}

void PBXSourcesBuildPhase::Visit(PBXObjectVisitor& visitor) {
  PBXBuildPhase::Visit(visitor);
  for (const auto& file : files_) {
    file->Visit(visitor);
  }
}

void PBXSourcesBuildPhase::Visit(PBXObjectVisitorConst& visitor) const {
  PBXBuildPhase::Visit(visitor);
  for (const auto& file : files_) {
    file->Visit(visitor);
  }
}

void PBXSourcesBuildPhase::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {false, indent + 1};
  out << indent_str << Reference() << " = {\n";
  PrintProperty(out, rules, "isa", ToString(Class()));
  PrintProperty(out, rules, "buildActionMask", 0x7fffffffu);
  PrintProperty(out, rules, "files", files_);
  PrintProperty(out, rules, "runOnlyForDeploymentPostprocessing", 0u);
  out << indent_str << "};\n";
}

PBXTargetDependency::PBXTargetDependency(
    const PBXTarget* target,
    std::unique_ptr<PBXContainerItemProxy> container_item_proxy)
    : target_(target), container_item_proxy_(std::move(container_item_proxy)) {}

PBXTargetDependency::~PBXTargetDependency() = default;

PBXObjectClass PBXTargetDependency::Class() const {
  return PBXTargetDependencyClass;
}

std::string PBXTargetDependency::Name() const {
  return "PBXTargetDependency";
}

void PBXTargetDependency::Visit(PBXObjectVisitor& visitor) {
  PBXObject::Visit(visitor);
  container_item_proxy_->Visit(visitor);
}

void PBXTargetDependency::Visit(PBXObjectVisitorConst& visitor) const {
  PBXObject::Visit(visitor);
  container_item_proxy_->Visit(visitor);
}

void PBXTargetDependency::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {false, indent + 1};
  out << indent_str << Reference() << " = {\n";
  PrintProperty(out, rules, "isa", ToString(Class()));
  PrintProperty(out, rules, "target", target_);
  PrintProperty(out, rules, "targetProxy", container_item_proxy_);
  out << indent_str << "};\n";
}

// XCBuildConfiguration -------------------------------------------------------

XCBuildConfiguration::XCBuildConfiguration(const std::string& name,
                                           const PBXAttributes& attributes)
    : attributes_(attributes), name_(name) {}

XCBuildConfiguration::~XCBuildConfiguration() = default;

PBXObjectClass XCBuildConfiguration::Class() const {
  return XCBuildConfigurationClass;
}

std::string XCBuildConfiguration::Name() const {
  return name_;
}

void XCBuildConfiguration::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {false, indent + 1};
  out << indent_str << Reference() << " = {\n";
  PrintProperty(out, rules, "isa", ToString(Class()));
  PrintProperty(out, rules, "buildSettings", attributes_);
  PrintProperty(out, rules, "name", name_);
  out << indent_str << "};\n";
}

// XCConfigurationList --------------------------------------------------------

XCConfigurationList::XCConfigurationList(const std::string& name,
                                         const PBXAttributes& attributes,
                                         const PBXObject* owner_reference)
    : owner_reference_(owner_reference) {
  DCHECK(owner_reference_);
  configurations_.push_back(
      std::make_unique<XCBuildConfiguration>(name, attributes));
}

XCConfigurationList::~XCConfigurationList() = default;

PBXObjectClass XCConfigurationList::Class() const {
  return XCConfigurationListClass;
}

std::string XCConfigurationList::Name() const {
  std::stringstream buffer;
  buffer << "Build configuration list for "
         << ToString(owner_reference_->Class()) << " \""
         << owner_reference_->Name() << "\"";
  return buffer.str();
}

void XCConfigurationList::Visit(PBXObjectVisitor& visitor) {
  PBXObject::Visit(visitor);
  for (const auto& configuration : configurations_) {
    configuration->Visit(visitor);
  }
}

void XCConfigurationList::Visit(PBXObjectVisitorConst& visitor) const {
  PBXObject::Visit(visitor);
  for (const auto& configuration : configurations_) {
    configuration->Visit(visitor);
  }
}

void XCConfigurationList::Print(std::ostream& out, unsigned indent) const {
  const std::string indent_str(indent, '\t');
  const IndentRules rules = {false, indent + 1};
  out << indent_str << Reference() << " = {\n";
  PrintProperty(out, rules, "isa", ToString(Class()));
  PrintProperty(out, rules, "buildConfigurations", configurations_);
  PrintProperty(out, rules, "defaultConfigurationIsVisible", 1u);
  PrintProperty(out, rules, "defaultConfigurationName",
                configurations_[0]->Name());
  out << indent_str << "};\n";
}
