// 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_FILESYSTEM_UTILS_H_
#define TOOLS_GN_FILESYSTEM_UTILS_H_

#include <stddef.h>

#include <string>
#include <string_view>

#include "base/files/file_path.h"
#include "gn/settings.h"
#include "gn/target.h"

class Err;

std::string FilePathToUTF8(const base::FilePath::StringType& str);
inline std::string FilePathToUTF8(const base::FilePath& path) {
  return FilePathToUTF8(path.value());
}
base::FilePath UTF8ToFilePath(std::string_view sp);

// Extensions -----------------------------------------------------------------

// Returns the index of the extension (character after the last dot not after a
// slash). Returns std::string::npos if not found. Returns path.size() if the
// file ends with a dot.
size_t FindExtensionOffset(std::string_view path);

// Returns a string piece pointing into the input string identifying the
// extension. Note that the input pointer must outlive the output.
std::string_view FindExtension(const std::string* path);

// Filename parts -------------------------------------------------------------

// Returns the offset of the character following the last slash, or
// 0 if no slash was found. Returns path.size() if the path ends with a slash.
// Note that the input pointer must outlive the output.
size_t FindFilenameOffset(const std::string& path);

// Returns a string piece pointing into the input string identifying the
// file name (following the last slash, including the extension). Note that the
// input pointer must outlive the output.
std::string_view FindFilename(const std::string* path);

// Like FindFilename but does not include the extension.
std::string_view FindFilenameNoExtension(const std::string* path);

// Removes everything after the last slash. The last slash, if any, will be
// preserved.
void RemoveFilename(std::string* path);

// Returns if the given character is a slash. This allows both slashes and
// backslashes for consistency between Posix and Windows (as opposed to
// FilePath::IsSeparator which is based on the current platform).
inline bool IsSlash(const char ch) {
  return ch == '/' || ch == '\\';
}

// Returns true if the given path ends with a slash.
bool EndsWithSlash(std::string_view s);

// Path parts -----------------------------------------------------------------

// Returns a string piece pointing into the input string identifying the
// directory name of the given path, including the last slash. Note that the
// input pointer must outlive the output.
std::string_view FindDir(const std::string* path);

// Returns the substring identifying the last component of the dir, or the
// empty substring if none. For example "//foo/bar/" -> "bar".
std::string_view FindLastDirComponent(const SourceDir& dir);

// Returns true if the given string is in the given output dir. This is pretty
// stupid and doesn't handle "." and "..", etc., it is designed for a sanity
// check to keep people from writing output files to the source directory
// accidentally.
bool IsStringInOutputDir(const SourceDir& output_dir, const std::string& str);

// Verifies that the given string references a file inside of the given
// directory. This just uses IsStringInOutputDir above.
//
// The origin will be blamed in the error.
//
// If the file isn't in the dir, returns false and sets the error. Otherwise
// returns true and leaves the error untouched.
bool EnsureStringIsInOutputDir(const SourceDir& output_dir,
                               const std::string& str,
                               const ParseNode* origin,
                               Err* err);

// ----------------------------------------------------------------------------

// Returns true if the input string is absolute. Double-slashes at the
// beginning are treated as source-relative paths. On Windows, this handles
// paths of both the native format: "C:/foo" and ours "/C:/foo"
bool IsPathAbsolute(std::string_view path);

// Returns true if the input string is source-absolute. Source-absolute
// paths begin with two forward slashes and resolve as if they are
// relative to the source root.
bool IsPathSourceAbsolute(std::string_view path);

// Given an absolute path, checks to see if is it is inside the source root.
// If it is, fills a source-absolute path into the given output and returns
// true. If it isn't, clears the dest and returns false.
//
// The source_root should be a base::FilePath converted to UTF-8. On Windows,
// it should begin with a "C:/" rather than being our SourceFile's style
// ("/C:/"). The source root can end with a slash or not.
//
// Note that this does not attempt to normalize slashes in the output.
bool MakeAbsolutePathRelativeIfPossible(std::string_view source_root,
                                        std::string_view path,
                                        std::string* dest);

// Given two absolute paths |base| and |target|, returns a relative path to
// |target| as if the current directory was |base|.  The relative path returned
// is minimal.  For example, if "../../a/b/" and "../b" are both valid, then the
// latter will be returned.  On Windows, it's impossible to have a relative path
// from C:\foo to D:\bar, so the absolute path |target| is returned instead for
// this case.
base::FilePath MakeAbsoluteFilePathRelativeIfPossible(
    const base::FilePath& base,
    const base::FilePath& target);

// Collapses "." and sequential "/"s and evaluates "..". |path| may be
// system-absolute, source-absolute, or relative. If |path| is source-absolute
// and |source_root| is non-empty, |path| may be system absolute after this
// function returns, if |path| references the filesystem outside of
// |source_root| (ex. path = "//.."). In this case on Windows, |path| will have
// a leading slash. Otherwise, |path| will retain its relativity. |source_root|
// must not end with a slash.
void NormalizePath(std::string* path,
                   std::string_view source_root = std::string_view());

// Converts slashes to backslashes for Windows. Keeps the string unchanged
// for other systems.
void ConvertPathToSystem(std::string* path);

// Takes a path, |input|, and makes it relative to the given directory
// |dest_dir|. Both inputs may be source-relative (e.g. begins with
// with "//") or may be absolute.
//
// If supplied, the |source_root| parameter is the absolute path to
// the source root and not end in a slash. Unless you know that the
// inputs are always source relative, this should be supplied.
std::string RebasePath(const std::string& input,
                       const SourceDir& dest_dir,
                       std::string_view source_root = std::string_view());

// Resolves a file or dir name (parameter input) relative to
// value directory. Will return an empty SourceDir/File on error
// and set the give *err pointer (required). Empty input is always an error.
// Returned value can be used to set value in either SourceFile or SourceDir
// (based on as_file parameter).
//
// Parameter as_file defines whether result path will look like a file path
// or it should be treated as a directory (contains "/" and the end
// of the string).
//
// If source_root is supplied, these functions will additionally handle the
// case where the input is a system-absolute but still inside the source
// tree. This is the case for some external tools.
std::string ResolveRelative(std::string_view input,
                            const std::string& value,
                            bool as_file,
                            std::string_view source_root);

// Resolves source file or directory relative to some given source root. Returns
// an empty file path on error.
base::FilePath ResolvePath(const std::string& value,
                           bool as_file,
                           const base::FilePath& source_root);

// Returns the given directory with no terminating slash at the end, such that
// appending a slash and more stuff will produce a valid path.
//
// If the directory refers to either the source or system root, we'll append
// a "." so this remains valid.
std::string DirectoryWithNoLastSlash(const SourceDir& dir);

// Returns the "best" SourceDir representing the given path. If it's inside the
// given source_root, a source-relative directory will be returned (e.g.
// "//foo/bar.cc". If it's outside of the source root or the source root is
// empty, a system-absolute directory will be returned.
SourceDir SourceDirForPath(const base::FilePath& source_root,
                           const base::FilePath& path);

// Like SourceDirForPath but returns the SourceDir representing the current
// directory.
SourceDir SourceDirForCurrentDirectory(const base::FilePath& source_root);

// Given the label of a toolchain and whether that toolchain is the default
// toolchain, returns the name of the subdirectory for that toolchain's
// output. This will be the empty string to indicate that the toolchain outputs
// go in the root build directory. Otherwise, the result will end in a slash.
std::string GetOutputSubdirName(const Label& toolchain_label, bool is_default);

// Returns true if the contents of the file and stream given are equal, false
// otherwise.
bool ContentsEqual(const base::FilePath& file_path, const std::string& data);

// Writes given stream contents to the given file. Returns true if data was
// successfully written, false otherwise. |err| is set on error if not nullptr.
bool WriteFile(const base::FilePath& file_path,
               const std::string& data,
               Err* err);

// -----------------------------------------------------------------------------

enum class BuildDirType {
  // Returns the root toolchain dir rather than the generated or output
  // subdirectories. This is valid only for the toolchain directory getters.
  // Asking for this for a target or source dir makes no sense.
  TOOLCHAIN_ROOT,

  // Generated file directory.
  GEN,

  // Output file directory.
  OBJ,

  // Phony file directory. As the name implies, this is not a real file
  // directory, but a path that is used for the declaration of phony targets.
  // This is done to avoid duplicate target names between real files and phony
  // aliases that point to them.
  PHONY,
};

// In different contexts, different information is known about the toolchain in
// question. If you have a Target or settings object, everything can be
// extracted from there. But when querying label information on something in
// another toolchain, for example, the only thing known (it may not even exist)
// is the toolchain label string and whether it matches the default toolchain.
//
// This object extracts the relevant information from a variety of input
// types for the convenience of the caller.
class BuildDirContext {
 public:
  // Extracts toolchain information associated with the given target.
  explicit BuildDirContext(const Target* target);

  // Extracts toolchain information associated with the given settings object.
  explicit BuildDirContext(const Settings* settings);

  // Extrats toolchain information from the current toolchain of the scope.
  explicit BuildDirContext(const Scope* execution_scope);

  // Extracts the default toolchain information from the given execution
  // scope. The toolchain you want to query must be passed in. This doesn't
  // use the settings object from the Scope so one can query other toolchains.
  // If you want to use the scope's current toolchain, use the version above.
  BuildDirContext(const Scope* execution_scope, const Label& toolchain_label);

  // Specify all information manually.
  BuildDirContext(const BuildSettings* build_settings,
                  const Label& toolchain_label,
                  bool is_default_toolchain);

  const BuildSettings* build_settings;
  const Label& toolchain_label;
  bool is_default_toolchain;
};

// Returns the root, object, or generated file directory for the toolchain.
//
// The toolchain object file root is never exposed in GN (there is no
// root_obj_dir variable) so BuildDirType::OBJ would normally never be passed
// to this function except when it's called by one of the variants below that
// append paths to it.
SourceDir GetSourceDir(const BuildDirContext& context, BuildDirType type);
std::string GetBuildDir(const BuildDirContext& context, BuildDirType type);

// Returns the output or generated file directory corresponding to the given
// source directory.
SourceDir GetSourceDir(const BuildDirContext& context,
                       const SourceDir& source_dir,
                       BuildDirType type);
std::string GetBuildDir(const BuildDirContext& context,
                        const SourceDir& source_dir,
                        BuildDirType type);

// Returns the output or generated file directory corresponding to the given
// target.
SourceDir GetSourceDir(const Target& target, BuildDirType type);
std::string GetBuildDir(const Target& target, BuildDirType type);

// Returns the scope's current directory.
SourceDir GetSourceDir(const Scope& scope, BuildDirType type);
// Lack of GetBuildDir version is due only to it not currently being needed,
// please add one if you need it.

template <typename... Args>
OutputFile GetOutputFile(const BuildDirContext& context,
                         BuildDirType type,
                         Args&&... args) {
  std::string path = GetBuildDir(context, type);
  (path.append(std::forward<Args>(args)), ...);
  return OutputFile(path);
}

template <typename... Args>
OutputFile GetOutputFile(const BuildDirContext& context,
                         const SourceDir& source_dir,
                         BuildDirType type,
                         Args&&... args) {
  std::string path = GetBuildDir(context, source_dir, type);
  (path.append(std::forward<Args>(args)), ...);
  return OutputFile(path);
}

template <typename... Args>
OutputFile GetOutputFile(const Target& target,
                         BuildDirType type,
                         Args&&... args) {
  std::string path = GetBuildDir(target, type);
  (path.append(std::forward<Args>(args)), ...);
  return OutputFile(path);
}

#endif  // TOOLS_GN_FILESYSTEM_UTILS_H_
