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

#include <stddef.h>
#include <utility>

#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "tools/gn/scope.h"

// NOTE: Cannot use = default here due to the use of a union member.
Value::Value() {}

Value::Value(const ParseNode* origin, Type t) : type_(t), origin_(origin) {
  switch (type_) {
    case NONE:
      break;
    case BOOLEAN:
      boolean_value_ = false;
      break;
    case INTEGER:
      int_value_ = 0;
      break;
    case STRING:
      new (&string_value_) std::string();
      break;
    case LIST:
      new (&list_value_) std::vector<Value>();
      break;
    case SCOPE:
      new (&scope_value_) std::unique_ptr<Scope>();
      break;
  }
}

Value::Value(const ParseNode* origin, bool bool_val)
    : type_(BOOLEAN), boolean_value_(bool_val), origin_(origin) {}

Value::Value(const ParseNode* origin, int64_t int_val)
    : type_(INTEGER), int_value_(int_val), origin_(origin) {}

Value::Value(const ParseNode* origin, std::string str_val)
    : type_(STRING), string_value_(std::move(str_val)), origin_(origin) {}

Value::Value(const ParseNode* origin, const char* str_val)
    : type_(STRING), string_value_(str_val), origin_(origin) {}

Value::Value(const ParseNode* origin, std::unique_ptr<Scope> scope)
    : type_(SCOPE), scope_value_(std::move(scope)), origin_(origin) {}

Value::Value(const Value& other) : type_(other.type_), origin_(other.origin_) {
  switch (type_) {
    case NONE:
      break;
    case BOOLEAN:
      boolean_value_ = other.boolean_value_;
      break;
    case INTEGER:
      int_value_ = other.int_value_;
      break;
    case STRING:
      new (&string_value_) std::string(other.string_value_);
      break;
    case LIST:
      new (&list_value_) std::vector<Value>(other.list_value_);
      break;
    case SCOPE:
      new (&scope_value_) std::unique_ptr<Scope>(
          other.scope_value_.get() ? other.scope_value_->MakeClosure()
                                   : nullptr);
      break;
  }
}

Value::Value(Value&& other) noexcept
    : type_(other.type_), origin_(other.origin_) {
  switch (type_) {
    case NONE:
      break;
    case BOOLEAN:
      boolean_value_ = other.boolean_value_;
      break;
    case INTEGER:
      int_value_ = other.int_value_;
      break;
    case STRING:
      new (&string_value_) std::string(std::move(other.string_value_));
      break;
    case LIST:
      new (&list_value_) std::vector<Value>(std::move(other.list_value_));
      break;
    case SCOPE:
      new (&scope_value_) std::unique_ptr<Scope>(std::move(other.scope_value_));
      break;
  }
}

Value& Value::operator=(const Value& other) {
  if (this != &other) {
    this->~Value();
    new (this) Value(other);
  }
  return *this;
}

Value& Value::operator=(Value&& other) noexcept {
  if (this != &other) {
    this->~Value();
    new (this) Value(std::move(other));
  }
  return *this;
}

Value::~Value() {
  using namespace std;
  switch (type_) {
    case STRING:
      string_value_.~string();
      break;
    case LIST:
      list_value_.~vector<Value>();
      break;
    case SCOPE:
      scope_value_.~unique_ptr<Scope>();
      break;
    default:;
  }
}

// static
const char* Value::DescribeType(Type t) {
  switch (t) {
    case NONE:
      return "none";
    case BOOLEAN:
      return "boolean";
    case INTEGER:
      return "integer";
    case STRING:
      return "string";
    case LIST:
      return "list";
    case SCOPE:
      return "scope";
    default:
      NOTREACHED();
      return "UNKNOWN";
  }
}

void Value::SetScopeValue(std::unique_ptr<Scope> scope) {
  DCHECK(type_ == SCOPE);
  scope_value_ = std::move(scope);
}

std::string Value::ToString(bool quote_string) const {
  switch (type_) {
    case NONE:
      return "<void>";
    case BOOLEAN:
      return boolean_value_ ? "true" : "false";
    case INTEGER:
      return base::Int64ToString(int_value_);
    case STRING:
      if (quote_string) {
        std::string result = "\"";
        bool hanging_backslash = false;
        for (char ch : string_value_) {
          // If the last character was a literal backslash and the next
          // character could form a valid escape sequence, we need to insert
          // an extra backslash to prevent that.
          if (hanging_backslash && (ch == '$' || ch == '"' || ch == '\\'))
            result += '\\';
          // If the next character is a dollar sign or double quote, it needs
          // to be escaped; otherwise it can be printed as is.
          if (ch == '$' || ch == '"')
            result += '\\';
          result += ch;
          hanging_backslash = (ch == '\\');
        }
        // Again, we need to prevent the closing double quotes from becoming
        // an escape sequence.
        if (hanging_backslash)
          result += '\\';
        result += '"';
        return result;
      }
      return string_value_;
    case LIST: {
      std::string result = "[";
      for (size_t i = 0; i < list_value_.size(); i++) {
        if (i > 0)
          result += ", ";
        result += list_value_[i].ToString(true);
      }
      result.push_back(']');
      return result;
    }
    case SCOPE: {
      Scope::KeyValueMap scope_values;
      scope_value_->GetCurrentScopeValues(&scope_values);
      if (scope_values.empty())
        return std::string("{ }");

      std::string result = "{\n";
      for (const auto& pair : scope_values) {
        result += "  " + std::string(pair.first) + " = " +
                  pair.second.ToString(true) + "\n";
      }
      result += "}";

      return result;
    }
  }
  return std::string();
}

bool Value::VerifyTypeIs(Type t, Err* err) const {
  if (type_ == t)
    return true;

  *err = Err(origin(), std::string("This is not a ") + DescribeType(t) + ".",
             std::string("Instead I see a ") + DescribeType(type_) + " = " +
                 ToString(true));
  return false;
}

bool Value::operator==(const Value& other) const {
  if (type_ != other.type_)
    return false;

  switch (type_) {
    case Value::BOOLEAN:
      return boolean_value() == other.boolean_value();
    case Value::INTEGER:
      return int_value() == other.int_value();
    case Value::STRING:
      return string_value() == other.string_value();
    case Value::LIST:
      if (list_value().size() != other.list_value().size())
        return false;
      for (size_t i = 0; i < list_value().size(); i++) {
        if (list_value()[i] != other.list_value()[i])
          return false;
      }
      return true;
    case Value::SCOPE:
      return scope_value()->CheckCurrentScopeValuesEqual(other.scope_value());
    case Value::NONE:
      return false;
    default:
      NOTREACHED();
      return false;
  }
}

bool Value::operator!=(const Value& other) const {
  return !operator==(other);
}
