// 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 "tools/gn/settings.h"
#include "tools/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& 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,
};

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