// 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(const 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(const std::string& 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(const 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(const 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(const 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(const std::string_view& source_root,
                                        const 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,
                   const 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,
    const 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.
template <typename StringType>
std::string ResolveRelative(const StringType& input,
                            const std::string& value,
                            bool as_file,
                            const 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 if it differs from existing
// file contents. Returns true if new contents was successfully written or
// existing file contents doesn't need updating, false on write error. |err| is
// set on write error if not nullptr.
bool WriteFileIfChanged(const base::FilePath& file_path,
                        const std::string& data,
                        Err* err);

// 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 GetBuildDirAsSourceDir(const BuildDirContext& context,
                                 BuildDirType type);
OutputFile GetBuildDirAsOutputFile(const BuildDirContext& context,
                                   BuildDirType type);

// Returns the output or generated file directory corresponding to the given
// source directory.
SourceDir GetSubBuildDirAsSourceDir(const BuildDirContext& context,
                                    const SourceDir& source_dir,
                                    BuildDirType type);
OutputFile GetSubBuildDirAsOutputFile(const BuildDirContext& context,
                                      const SourceDir& source_dir,
                                      BuildDirType type);

// Returns the output or generated file directory corresponding to the given
// target.
SourceDir GetBuildDirForTargetAsSourceDir(const Target* target,
                                          BuildDirType type);
OutputFile GetBuildDirForTargetAsOutputFile(const Target* target,
                                            BuildDirType type);

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

#endif  // TOOLS_GN_FILESYSTEM_UTILS_H_
