// 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.

#ifndef TOOLS_GN_PATH_OUTPUT_H_
#define TOOLS_GN_PATH_OUTPUT_H_

#include <iosfwd>
#include <string>
#include <string_view>

#include "base/macros.h"
#include "tools/gn/escape.h"
#include "tools/gn/source_dir.h"
#include "tools/gn/unique_vector.h"

class OutputFile;
class SourceFile;

namespace base {
class FilePath;
}

// Writes file names to streams assuming a certain input directory and
// escaping rules. This gives us a central place for managing this state.
class PathOutput {
 public:
  // Controls whether writing directory names include the trailing slash.
  // Often we don't want the trailing slash when writing out to a command line,
  // especially on Windows where it's a backslash and might be interpreted as
  // escaping the thing following it.
  enum DirSlashEnding {
    DIR_INCLUDE_LAST_SLASH,
    DIR_NO_LAST_SLASH,
  };

  PathOutput(const SourceDir& current_dir,
             const std::string_view& source_root,
             EscapingMode escaping);
  ~PathOutput();

  // Read-only since inverse_current_dir_ is computed depending on this.
  EscapingMode escaping_mode() const { return options_.mode; }

  const SourceDir& current_dir() const { return current_dir_; }

  // Getter/setters for flags inside the escape options.
  bool inhibit_quoting() const { return options_.inhibit_quoting; }
  void set_inhibit_quoting(bool iq) { options_.inhibit_quoting = iq; }
  void set_escape_platform(EscapingPlatform p) { options_.platform = p; }

  void WriteFile(std::ostream& out, const SourceFile& file) const;
  void WriteFile(std::ostream& out, const OutputFile& file) const;
  void WriteFile(std::ostream& out, const base::FilePath& file) const;

  // Writes the given OutputFiles with spaces separating them. This will also
  // write an initial space before the first item.
  void WriteFiles(std::ostream& out,
                  const std::vector<OutputFile>& files) const;
  void WriteFiles(std::ostream& out,
                  const UniqueVector<OutputFile>& files) const;

  // This variant assumes the dir ends in a trailing slash or is empty.
  void WriteDir(std::ostream& out,
                const SourceDir& dir,
                DirSlashEnding slash_ending) const;

  void WriteDir(std::ostream& out,
                const OutputFile& file,
                DirSlashEnding slash_ending) const;

  // Backend for WriteFile and WriteDir. This appends the given file or
  // directory string to the file.
  void WritePathStr(std::ostream& out, const std::string_view& str) const;

 private:
  // Takes the given string and writes it out, appending to the inverse
  // current dir. This assumes leading slashes have been trimmed.
  void WriteSourceRelativeString(std::ostream& out,
                                 const std::string_view& str) const;

  SourceDir current_dir_;

  // Uses system slashes if convert_slashes_to_system_.
  std::string inverse_current_dir_;

  // Since the inverse_current_dir_ depends on some of these, we don't expose
  // this directly to modification.
  EscapeOptions options_;
};

#endif  // TOOLS_GN_PATH_OUTPUT_H_
