// 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 "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 int 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;
  Label empty_label;
  Toolchain toolchain(empty_label);
  Settings settings(&build_settings, &toolchain, 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

/*
input_conversion: Specifies how to transform input to a variable.

  input_conversion is an argument to read_file and exec_script that specifies
  how the result of the read operation should be converted into a variable.

  "list lines":
      Return the file contents as a list, with a string for each line. The
      newlines will not be present in the result. Empty newlines will be
      trimmed from the trailing end of the returned list.

  "value":
      Parse the input as if it was a literal rvalue in a buildfile.
      Examples of typical program output using this mode:
        [ "foo", "bar" ]     (result will be a list)
      or
        "foo bar"            (result will be a string)
      or
        5                    (result will be an integer)

      Note that if the input is empty, the result will be a null value which
      will produce an error if assigned to a variable.

  "string":
      Return the file contents into a single string.
*/

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