// 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 "tools/gn/filesystem_utils.h"
#include "tools/gn/source_file.h"
#include "util/build_config.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.SetValue(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;
