// 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 "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, EscapingMode escaping)
    : current_dir_(current_dir) {
  CHECK(current_dir.is_source_absolute())
      << "Currently this only supports writing to output directories inside "
         "the source root. There needs to be some tweaks to PathOutput to make "
         "doing this work correctly.";
  inverse_current_dir_ = InvertDir(current_dir_);

  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::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
  }
}
