// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "dbus/values_util.h"

#include <memory>
#include <utility>

#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "base/values.h"
#include "dbus/message.h"

namespace dbus {

namespace {

// Returns whether |value| is exactly representable by double or not.
template <typename T>
bool IsExactlyRepresentableByDouble(T value) {
  return value == static_cast<T>(static_cast<double>(value));
}

// Pops values from |reader| and appends them to |list_value|.
bool PopListElements(MessageReader* reader, base::Value* list_value) {
  DCHECK(list_value->is_list());
  while (reader->HasMoreData()) {
    base::Value element_value = PopDataAsValue(reader);
    if (element_value.is_none())
      return false;
    list_value->Append(std::move(element_value));
  }
  return true;
}

// Pops dict-entries from |reader| and sets them to |dictionary_value|
bool PopDictionaryEntries(MessageReader* reader,
                          base::Value* dictionary_value) {
  DCHECK(dictionary_value->is_dict());
  while (reader->HasMoreData()) {
    DCHECK_EQ(Message::DICT_ENTRY, reader->GetDataType());
    MessageReader entry_reader(nullptr);
    if (!reader->PopDictEntry(&entry_reader))
      return false;
    // Get key as a string.
    std::string key_string;
    if (entry_reader.GetDataType() == Message::STRING) {
      // If the type of keys is STRING, pop it directly.
      if (!entry_reader.PopString(&key_string))
        return false;
    } else {
      // If the type of keys is not STRING, convert it to string.
      base::Value key = PopDataAsValue(&entry_reader);
      if (key.is_none())
        return false;
      // Use JSONWriter to convert an arbitrary value to a string.
      base::JSONWriter::Write(key, &key_string);
    }
    // Get the value and set the key-value pair.
    base::Value value = PopDataAsValue(&entry_reader);
    if (value.is_none())
      return false;
    dictionary_value->SetKey(key_string, std::move(value));
  }
  return true;
}

// Gets the D-Bus type signature for the value.
std::string GetTypeSignature(base::ValueView value) {
  struct Visitor {
    std::string operator()(absl::monostate) {
      DLOG(ERROR) << "Unexpected type " << base::Value::Type::NONE;
      return std::string();
    }

    std::string operator()(bool) { return "b"; }

    std::string operator()(int) { return "i"; }

    std::string operator()(double) { return "d"; }

    std::string operator()(base::StringPiece) { return "s"; }

    std::string operator()(const base::Value::BlobStorage&) { return "ay"; }

    std::string operator()(const base::Value::Dict&) { return "a{sv}"; }

    std::string operator()(const base::Value::List&) { return "av"; }
  };
  return value.Visit(Visitor());
}

}  // namespace

base::Value PopDataAsValue(MessageReader* reader) {
  base::Value result;
  switch (reader->GetDataType()) {
    case Message::INVALID_DATA:
      // Do nothing.
      break;
    case Message::BYTE: {
      uint8_t value = 0;
      if (reader->PopByte(&value))
        result = base::Value(value);
      break;
    }
    case Message::BOOL: {
      bool value = false;
      if (reader->PopBool(&value))
        result = base::Value(value);
      break;
    }
    case Message::INT16: {
      int16_t value = 0;
      if (reader->PopInt16(&value))
        result = base::Value(value);
      break;
    }
    case Message::UINT16: {
      uint16_t value = 0;
      if (reader->PopUint16(&value))
        result = base::Value(value);
      break;
    }
    case Message::INT32: {
      int32_t value = 0;
      if (reader->PopInt32(&value))
        result = base::Value(value);
      break;
    }
    case Message::UINT32: {
      uint32_t value = 0;
      if (reader->PopUint32(&value)) {
        result = base::Value(static_cast<double>(value));
      }
      break;
    }
    case Message::INT64: {
      int64_t value = 0;
      if (reader->PopInt64(&value)) {
        DLOG_IF(WARNING, !IsExactlyRepresentableByDouble(value))
            << value << " is not exactly representable by double";
        result = base::Value(static_cast<double>(value));
      }
      break;
    }
    case Message::UINT64: {
      uint64_t value = 0;
      if (reader->PopUint64(&value)) {
        DLOG_IF(WARNING, !IsExactlyRepresentableByDouble(value))
            << value << " is not exactly representable by double";
        result = base::Value(static_cast<double>(value));
      }
      break;
    }
    case Message::DOUBLE: {
      double value = 0;
      if (reader->PopDouble(&value))
        result = base::Value(value);
      break;
    }
    case Message::STRING: {
      std::string value;
      if (reader->PopString(&value))
        result = base::Value(value);
      break;
    }
    case Message::OBJECT_PATH: {
      ObjectPath value;
      if (reader->PopObjectPath(&value))
        result = base::Value(value.value());
      break;
    }
    case Message::UNIX_FD: {
      // Cannot distinguish a file descriptor from an int
      NOTREACHED();
      break;
    }
    case Message::ARRAY: {
      MessageReader sub_reader(nullptr);
      if (reader->PopArray(&sub_reader)) {
        // If the type of the array's element is DICT_ENTRY, create a
        // Value with type base::Value::Type::DICTIONARY, otherwise create a
        // Value with type base::Value::Type::LIST.
        if (sub_reader.GetDataType() == Message::DICT_ENTRY) {
          auto dictionary_value = base::Value(base::Value::Type::DICTIONARY);
          if (PopDictionaryEntries(&sub_reader, &dictionary_value))
            result = std::move(dictionary_value);
        } else {
          auto list_value = base::Value(base::Value::Type::LIST);
          if (PopListElements(&sub_reader, &list_value))
            result = std::move(list_value);
        }
      }
      break;
    }
    case Message::STRUCT: {
      MessageReader sub_reader(nullptr);
      if (reader->PopStruct(&sub_reader)) {
        auto list_value = base::Value(base::Value::Type::LIST);
        if (PopListElements(&sub_reader, &list_value))
          result = std::move(list_value);
      }
      break;
    }
    case Message::DICT_ENTRY:
      // DICT_ENTRY must be popped as an element of an array.
      NOTREACHED();
      break;
    case Message::VARIANT: {
      MessageReader sub_reader(nullptr);
      if (reader->PopVariant(&sub_reader))
        result = PopDataAsValue(&sub_reader);
      break;
    }
  }
  return result;
}

void AppendBasicTypeValueData(MessageWriter* writer, base::ValueView value) {
  struct Visitor {
    MessageWriter* writer;

    void operator()(absl::monostate) {
      DLOG(ERROR) << "Unexpected type: " << base::Value::Type::NONE;
    }

    void operator()(bool value) { writer->AppendBool(value); }

    void operator()(int value) { writer->AppendInt32(value); }

    void operator()(double value) { writer->AppendDouble(value); }

    void operator()(base::StringPiece value) { writer->AppendString(value); }

    void operator()(const base::Value::BlobStorage&) {
      DLOG(ERROR) << "Unexpected type: " << base::Value::Type::BINARY;
    }

    void operator()(const base::Value::Dict&) {
      DLOG(ERROR) << "Unexpected type: " << base::Value::Type::DICT;
    }

    void operator()(const base::Value::List&) {
      DLOG(ERROR) << "Unexpected type: " << base::Value::Type::LIST;
    }
  };

  value.Visit(Visitor{.writer = writer});
}

void AppendBasicTypeValueDataAsVariant(MessageWriter* writer,
                                       base::ValueView value) {
  MessageWriter sub_writer(nullptr);
  writer->OpenVariant(GetTypeSignature(value), &sub_writer);
  AppendBasicTypeValueData(&sub_writer, value);
  writer->CloseContainer(&sub_writer);
}

void AppendValueData(MessageWriter* writer, base::ValueView value) {
  struct Visitor {
    MessageWriter* writer;

    void operator()(absl::monostate) {
      DLOG(ERROR) << "Unexpected type: " << base::Value::Type::NONE;
    }

    void operator()(bool value) {
      return AppendBasicTypeValueData(writer, value);
    }

    void operator()(int value) {
      return AppendBasicTypeValueData(writer, value);
    }

    void operator()(double value) {
      return AppendBasicTypeValueData(writer, value);
    }

    void operator()(base::StringPiece value) {
      return AppendBasicTypeValueData(writer, value);
    }

    void operator()(const base::Value::BlobStorage& value) {
      DLOG(ERROR) << "Unexpected type: " << base::Value::Type::BINARY;
    }

    void operator()(const base::Value::Dict& value) {
      dbus::MessageWriter array_writer(nullptr);
      writer->OpenArray("{sv}", &array_writer);
      for (auto item : value) {
        dbus::MessageWriter dict_entry_writer(nullptr);
        array_writer.OpenDictEntry(&dict_entry_writer);
        dict_entry_writer.AppendString(item.first);
        AppendValueDataAsVariant(&dict_entry_writer, item.second);
        array_writer.CloseContainer(&dict_entry_writer);
      }
      writer->CloseContainer(&array_writer);
    }

    void operator()(const base::Value::List& value) {
      dbus::MessageWriter array_writer(nullptr);
      writer->OpenArray("v", &array_writer);
      for (const auto& value_in_list : value) {
        AppendValueDataAsVariant(&array_writer, value_in_list);
      }
      writer->CloseContainer(&array_writer);
    }
  };

  value.Visit(Visitor{.writer = writer});
}

void AppendValueDataAsVariant(MessageWriter* writer, base::ValueView value) {
  MessageWriter variant_writer(nullptr);
  writer->OpenVariant(GetTypeSignature(value), &variant_writer);
  AppendValueData(&variant_writer, value);
  writer->CloseContainer(&variant_writer);
}

}  // namespace dbus
