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

#include "tools/gn/source_dir.h"

#include "base/logging.h"
#include "build_config.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/source_file.h"

namespace {

void AssertValueSourceDirString(const std::string& s) {
  if (!s.empty()) {
#if defined(OS_WIN)
    DCHECK(s[0] == '/' ||
           (s.size() > 2 && s[0] != '/' && s[1] == ':' && IsSlash(s[2])));
#else
    DCHECK(s[0] == '/');
#endif
    DCHECK(EndsWithSlash(s)) << s;
  }
}

// Validates input value (input_value) and sets proper error message.
// Note: Parameter blame_input is used only for generating error message.
template <typename StringType>
bool ValidateResolveInput(bool as_file,
                          const Value& blame_input_value,
                          const StringType& input_value,
                          Err* err) {
  if (as_file) {
    // It's an error to resolve an empty string or one that is a directory
    // (indicated by a trailing slash) because this is the function that expects
    // to return a file.
    if (input_value.empty()) {
      *err = Err(blame_input_value, "Empty file path.",
                 "You can't use empty strings as file paths.");
      return false;
    } else if (input_value[input_value.size() - 1] == '/') {
      std::string help = "You specified the path\n  ";
      help.append(std::string(input_value));
      help.append(
          "\nand it ends in a slash, indicating you think it's a directory."
          "\nBut here you're supposed to be listing a file.");
      *err = Err(blame_input_value, "File path ends in a slash.", help);
      return false;
    }
  } else if (input_value.empty()) {
    *err = Err(blame_input_value, "Empty directory path.",
               "You can't use empty strings as directories.");
    return false;
  }
  return true;
}

}  // namespace

SourceDir::SourceDir() = default;

SourceDir::SourceDir(const base::StringPiece& p) : value_(p.data(), p.size()) {
  if (!EndsWithSlash(value_))
    value_.push_back('/');
  AssertValueSourceDirString(value_);
}

SourceDir::SourceDir(SwapIn, std::string* s) {
  value_.swap(*s);
  if (!EndsWithSlash(value_))
    value_.push_back('/');
  AssertValueSourceDirString(value_);
}

SourceDir::~SourceDir() = default;

template <typename StringType>
std::string SourceDir::ResolveRelativeAs(
    bool as_file,
    const Value& blame_input_value,
    const StringType& input_value,
    Err* err,
    const base::StringPiece& source_root) const {
  if (!ValidateResolveInput<StringType>(as_file, blame_input_value, input_value,
                                        err)) {
    return std::string();
  }
  return ResolveRelative(input_value, value_, as_file, source_root);
}

SourceFile SourceDir::ResolveRelativeFile(
    const Value& p,
    Err* err,
    const base::StringPiece& source_root) const {
  SourceFile ret;

  if (!p.VerifyTypeIs(Value::STRING, err))
    return ret;

  const std::string& input_string = p.string_value();
  if (!ValidateResolveInput<std::string>(true, p, input_string, err)) {
    return ret;
  }
  ret.value_ = ResolveRelative(input_string, value_, true, source_root);
  return ret;
}

std::string SourceDir::ResolveRelativeAs(bool as_file,
                                         const Value& v,
                                         Err* err,
                                         const base::StringPiece& source_root,
                                         const std::string* v_value) const {
  if (!v.VerifyTypeIs(Value::STRING, err))
    return std::string();

  if (!v_value) {
    v_value = &v.string_value();
  }
  std::string result =
      ResolveRelativeAs(as_file, v, *v_value, err, source_root);
  if (!as_file)
    AssertValueSourceDirString(result);
  return result;
}

SourceDir SourceDir::ResolveRelativeDir(
    const Value& v,
    Err* err,
    const base::StringPiece& source_root) const {
  if (!v.VerifyTypeIs(Value::STRING, err))
    return SourceDir();

  return ResolveRelativeDir<std::string>(v, v.string_value(), err, source_root);
}

base::FilePath SourceDir::Resolve(const base::FilePath& source_root) const {
  return ResolvePath(value_, false, source_root);
}

void SourceDir::SwapValue(std::string* v) {
  value_.swap(*v);
  AssertValueSourceDirString(value_);
}

// Explicit template instantiation
template std::string SourceDir::ResolveRelativeAs(
    bool as_file,
    const Value& blame_input_value,
    const std::string& input_value,
    Err* err,
    const base::StringPiece& source_root) const;

template std::string SourceDir::ResolveRelativeAs(
    bool as_file,
    const Value& blame_input_value,
    const base::StringPiece& input_value,
    Err* err,
    const base::StringPiece& source_root) const;
