// Copyright (c) 2013 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/path_output.h"

#include "base/strings/string_util.h"
#include "gn/filesystem_utils.h"
#include "gn/output_file.h"
#include "gn/string_utils.h"
#include "util/build_config.h"

PathOutput::PathOutput(const SourceDir& current_dir,
                       const std::string_view& source_root,
                       EscapingMode escaping)
    : current_dir_(current_dir) {
  inverse_current_dir_ = RebasePath("//", current_dir, source_root);
  if (!EndsWithSlash(inverse_current_dir_))
    inverse_current_dir_.push_back('/');
  options_.mode = escaping;
}

PathOutput::~PathOutput() = default;

void PathOutput::WriteFile(std::ostream& out, const SourceFile& file) const {
  WritePathStr(out, file.value());
}

void PathOutput::WriteDir(std::ostream& out,
                          const SourceDir& dir,
                          DirSlashEnding slash_ending) const {
  if (dir.value() == "/") {
    // Writing system root is always a slash (this will normally only come up
    // on Posix systems).
    if (slash_ending == DIR_NO_LAST_SLASH)
      out << "/.";
    else
      out << "/";
  } else if (dir.value() == "//") {
    // Writing out the source root.
    if (slash_ending == DIR_NO_LAST_SLASH) {
      // The inverse_current_dir_ will contain a [back]slash at the end, so we
      // can't just write it out.
      if (inverse_current_dir_.empty()) {
        out << ".";
      } else {
        out.write(inverse_current_dir_.c_str(),
                  inverse_current_dir_.size() - 1);
      }
    } else {
      if (inverse_current_dir_.empty())
        out << "./";
      else
        out << inverse_current_dir_;
    }
  } else if (dir == current_dir_) {
    // Writing the same directory. This needs special handling here since
    // we need to output something else other than the input.
    if (slash_ending == DIR_INCLUDE_LAST_SLASH)
      out << "./";
    else
      out << ".";
  } else if (slash_ending == DIR_INCLUDE_LAST_SLASH) {
    WritePathStr(out, dir.value());
  } else {
    // DIR_NO_LAST_SLASH mode, just trim the last char.
    WritePathStr(out,
                 std::string_view(dir.value().data(), dir.value().size() - 1));
  }
}

void PathOutput::WriteFile(std::ostream& out, const OutputFile& file) const {
  // Here we assume that the path is already preprocessed.
  EscapeStringToStream(out, file.value(), options_);
}

void PathOutput::WriteFiles(std::ostream& out,
                            const std::vector<SourceFile>& files) const {
  for (const auto& file : files) {
    out << " ";
    WriteFile(out, file);
  }
}

void PathOutput::WriteFiles(std::ostream& out,
                            const std::vector<OutputFile>& files) const {
  for (const auto& file : files) {
    out << " ";
    WriteFile(out, file);
  }
}

void PathOutput::WriteFiles(std::ostream& out,
                            const UniqueVector<OutputFile>& files) const {
  for (const auto& file : files) {
    out << " ";
    WriteFile(out, file);
  }
}

void PathOutput::WriteDir(std::ostream& out,
                          const OutputFile& file,
                          DirSlashEnding slash_ending) const {
  DCHECK(file.value().empty() || file.value()[file.value().size() - 1] == '/');

  switch (slash_ending) {
    case DIR_INCLUDE_LAST_SLASH:
      EscapeStringToStream(out, file.value(), options_);
      break;
    case DIR_NO_LAST_SLASH:
      if (!file.value().empty() &&
          file.value()[file.value().size() - 1] == '/') {
        // Trim trailing slash.
        EscapeStringToStream(
            out, std::string_view(file.value().data(), file.value().size() - 1),
            options_);
      } else {
        // Doesn't end with a slash, write the whole thing.
        EscapeStringToStream(out, file.value(), options_);
      }
      break;
  }
}

void PathOutput::WriteFile(std::ostream& out,
                           const base::FilePath& file) const {
  // Assume native file paths are always absolute.
  EscapeStringToStream(out, FilePathToUTF8(file), options_);
}

void PathOutput::WriteSourceRelativeString(std::ostream& out,
                                           const std::string_view& str) const {
  if (options_.mode == ESCAPE_NINJA_COMMAND) {
    // Shell escaping needs an intermediate string since it may end up
    // quoting the whole thing.
    std::string intermediate;
    intermediate.reserve(inverse_current_dir_.size() + str.size());
    intermediate.assign(inverse_current_dir_.c_str(),
                        inverse_current_dir_.size());
    intermediate.append(str.data(), str.size());

    EscapeStringToStream(
        out, std::string_view(intermediate.c_str(), intermediate.size()),
        options_);
  } else {
    // Ninja (and none) escaping can avoid the intermediate string and
    // reprocessing of the inverse_current_dir_.
    out << inverse_current_dir_;
    EscapeStringToStream(out, str, options_);
  }
}

void PathOutput::WritePathStr(std::ostream& out,
                              const std::string_view& str) const {
  DCHECK(str.size() > 0 && str[0] == '/');

  if (str.substr(0, current_dir_.value().size()) ==
      std::string_view(current_dir_.value())) {
    // The current dir is a prefix of the output file, so we can strip the
    // prefix and write out the result.
    EscapeStringToStream(out, str.substr(current_dir_.value().size()),
                         options_);
  } else if (str.size() >= 2 && str[1] == '/') {
    WriteSourceRelativeString(out, str.substr(2));
  } else {
// Input begins with one slash, don't write the current directory since
// it's system-absolute.
#if defined(OS_WIN)
    // On Windows, trim the leading slash, since the input for absolute
    // paths will look like "/C:/foo/bar.txt".
    EscapeStringToStream(out, str.substr(1), options_);
#else
    EscapeStringToStream(out, str, options_);
#endif
  }
}
