// 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 "gn/escape.h"
#include "gn/source_dir.h"
#include "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,
             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 SourceFiles/OutputFiles with spaces separating them. This
  // will also write an initial space before the first item.
  void WriteFiles(std::ostream& out, const std::vector<SourceFile>& file) const;
  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, 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, 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_
