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

#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(const std::string& s) : value_(s) {
  if (!EndsWithSlash(value_))
    value_.push_back('/');
  AssertValueSourceDirString(value_);
}

SourceDir::SourceDir(std::string&& s) : value_(std::move(s)) {
  if (!EndsWithSlash(value_))
    value_.push_back('/');
  AssertValueSourceDirString(value_);
}

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);
}

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