// 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/input_conversion.h"

#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "tools/gn/build_settings.h"
#include "tools/gn/err.h"
#include "tools/gn/input_file.h"
#include "tools/gn/label.h"
#include "tools/gn/parse_tree.h"
#include "tools/gn/parser.h"
#include "tools/gn/scope.h"
#include "tools/gn/settings.h"
#include "tools/gn/tokenizer.h"
#include "tools/gn/value.h"

namespace {

// Returns the "first bit" of some script output for writing to error messages.
std::string GetExampleOfBadInput(const std::string& input) {
  std::string result(input);

  // Maybe the result starts with a blank line or something, which we don't
  // want.
  TrimWhitespaceASCII(result, TRIM_ALL, &result);

  // Now take the first line, or the first set of chars, whichever is shorter.
  bool trimmed = false;
  size_t newline_offset = result.find('\n');
  if (newline_offset != std::string::npos) {
    trimmed = true;
    result.resize(newline_offset);
  }
  TrimWhitespaceASCII(result, TRIM_ALL, &result);

  const size_t kMaxSize = 50;
  if (result.size() > kMaxSize) {
    trimmed = true;
    result.resize(kMaxSize);
  }

  if (trimmed)
    result.append("...");
  return result;
}

// When parsing the result as a value, we may get various types of errors.
// This creates an error message for this case with an optional nested error
// message to reference. If there is no nested err, pass Err().
//
// This code also takes care to rewrite the original error which will reference
// the temporary InputFile which won't exist when the error is propogated
// out to a higher level.
Err MakeParseErr(const std::string& input,
                 const ParseNode* origin,
                 const Err& nested) {
  std::string help_text =
      "When parsing a result as a \"value\" it should look like a list:\n"
      "  [ \"a\", \"b\", 5 ]\n"
      "or a single literal:\n"
      "  \"my result\"\n"
      "but instead I got this, which I find very confusing:\n";
  help_text.append(input);
  if (nested.has_error())
    help_text.append("\nThe exact error was:");

  Err result(origin, "Script result wasn't a valid value.", help_text);
  if (nested.has_error()) {
    result.AppendSubErr(Err(LocationRange(), nested.message(),
                            nested.help_text()));
  }
  return result;
}

// Sets the origin of the value and any nested values with the given node.
void RecursivelySetOrigin(Value* value, const ParseNode* origin) {
  value->set_origin(origin);
  if (value->type() == Value::LIST) {
    std::vector<Value>& list_value = value->list_value();
    for (size_t i = 0; i < list_value.size(); i++)
      RecursivelySetOrigin(&list_value[i], origin);
  }
}

Value ParseString(const std::string& input,
                  const ParseNode* origin,
                  Err* err) {
  SourceFile empty_source_for_most_vexing_parse;
  InputFile input_file(empty_source_for_most_vexing_parse);
  input_file.SetContents(input);

  std::vector<Token> tokens = Tokenizer::Tokenize(&input_file, err);
  if (err->has_error()) {
    *err = MakeParseErr(input, origin, *err);
    return Value();
  }

  scoped_ptr<ParseNode> expression = Parser::ParseExpression(tokens, err);
  if (err->has_error()) {
    *err = MakeParseErr(input, origin, *err);
    return Value();
  }

  // It's valid for the result to be a null pointer, this just means that the
  // script returned nothing.
  if (!expression)
    return Value();

  // The result should either be a list or a literal, anything else is
  // invalid.
  if (!expression->AsList() && !expression->AsLiteral()) {
    *err = MakeParseErr(input, origin, Err());
    return Value();
  }

  BuildSettings build_settings;
  Settings settings(&build_settings, std::string());
  Scope scope(&settings);

  Err nested_err;
  Value result = expression->Execute(&scope, &nested_err);
  if (nested_err.has_error()) {
    *err = MakeParseErr(input, origin, nested_err);
    return Value();
  }

  // The returned value will have references to the temporary parse nodes we
  // made on the stack. If the values are used in an error message in the
  // future, this will crash. Reset the origin of all values to be our
  // containing origin.
  RecursivelySetOrigin(&result, origin);
  return result;
}

Value ParseList(const std::string& input,
                const ParseNode* origin,
                Err* err) {
  Value ret(origin, Value::LIST);
  std::vector<std::string> as_lines;
  base::SplitString(input, '\n', &as_lines);

  // Trim empty lines from the end.
  // Do we want to make this configurable?
  while (!as_lines.empty() && as_lines[as_lines.size() - 1].empty())
    as_lines.resize(as_lines.size() - 1);

  ret.list_value().reserve(as_lines.size());
  for (size_t i = 0; i < as_lines.size(); i++)
    ret.list_value().push_back(Value(origin, as_lines[i]));
  return ret;
}

}  // namespace

extern const char kInputConversion_Help[] =
    "input_conversion: Specifies how to transform input to a variable.\n"
    "\n"
    "  input_conversion is an argument to read_file and exec_script that\n"
    "  specifies how the result of the read operation should be converted\n"
    "  into a variable.\n"
    "\n"
    "  \"list lines\"\n"
    "      Return the file contents as a list, with a string for each line.\n"
    "      The newlines will not be present in the result. Empty newlines\n"
    "      will be trimmed from the trailing end of the returned list.\n"
    "\n"
    "  \"value\"\n"
    "      Parse the input as if it was a literal rvalue in a buildfile.\n"
    "      Examples of typical program output using this mode:\n"
    "        [ \"foo\", \"bar\" ]     (result will be a list)\n"
    "      or\n"
    "        \"foo bar\"            (result will be a string)\n"
    "      or\n"
    "        5                    (result will be an integer)\n"
    "\n"
    "      Note that if the input is empty, the result will be a null value\n"
    "      which will produce an error if assigned to a variable.\n"
    "\n"
    "  \"string\"\n"
    "      Return the file contents into a single string.\n";

Value ConvertInputToValue(const std::string& input,
                          const ParseNode* origin,
                          const Value& input_conversion_value,
                          Err* err) {
  if (!input_conversion_value.VerifyTypeIs(Value::STRING, err))
    return Value();
  const std::string& input_conversion = input_conversion_value.string_value();

  if (input_conversion == "value")
    return ParseString(input, origin, err);
  if (input_conversion == "string")
    return Value(origin, input);
  if (input_conversion == "list lines")
    return ParseList(input, origin, err);

  *err = Err(input_conversion_value, "Not a valid read file mode.",
             "Have you considered a career in retail?");
  return Value();
}
