// 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 "tools/gn/path_output.h"

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

PathOutput::PathOutput(const SourceDir& current_dir,
                       const base::StringPiece& 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() {
}

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, base::StringPiece(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<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,
            base::StringPiece(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 base::StringPiece& 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,
        base::StringPiece(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 base::StringPiece& str) const {
  DCHECK(str.size() > 0 && str[0] == '/');

  if (str.substr(0, current_dir_.value().size()) ==
      base::StringPiece(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
  }
}
