// 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(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(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,
};

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