// Copyright (c) 2012 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 "dbus/values_util.h"

#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.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::ListValue* list_value) {
  while (reader->HasMoreData()) {
    base::Value* element_value = PopDataAsValue(reader);
    if (!element_value)
      return false;
    list_value->Append(element_value);
  }
  return true;
}

// Pops dict-entries from |reader| and sets them to |dictionary_value|
bool PopDictionaryEntries(MessageReader* reader,
                          base::DictionaryValue* dictionary_value) {
  while (reader->HasMoreData()) {
    DCHECK_EQ(Message::DICT_ENTRY, reader->GetDataType());
    MessageReader entry_reader(NULL);
    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.
      scoped_ptr<base::Value> key(PopDataAsValue(&entry_reader));
      if (!key.get())
        return false;
      // Use JSONWriter to convert an arbitrary value to a string.
      base::JSONWriter::Write(key.get(), &key_string);
    }
    // Get the value and set the key-value pair.
    base::Value* value = PopDataAsValue(&entry_reader);
    if (!value)
      return false;
    dictionary_value->SetWithoutPathExpansion(key_string, value);
  }
  return true;
}

// Gets the D-Bus type signature for the value.
std::string GetTypeSignature(const base::Value& value) {
  switch (value.GetType()) {
    case base::Value::TYPE_BOOLEAN:
      return "b";
    case base::Value::TYPE_INTEGER:
      return "i";
    case base::Value::TYPE_DOUBLE:
      return "d";
    case base::Value::TYPE_STRING:
      return "s";
    case base::Value::TYPE_BINARY:
      return "ay";
    case base::Value::TYPE_DICTIONARY:
      return "a{sv}";
    case base::Value::TYPE_LIST:
      return "av";
    default:
      DLOG(ERROR) << "Unexpected type " << value.GetType();
      return std::string();
  }
}

}  // namespace

base::Value* PopDataAsValue(MessageReader* reader) {
  base::Value* result = NULL;
  switch (reader->GetDataType()) {
    case Message::INVALID_DATA:
      // Do nothing.
      break;
    case Message::BYTE: {
      uint8 value = 0;
      if (reader->PopByte(&value))
        result = new base::FundamentalValue(value);
      break;
    }
    case Message::BOOL: {
      bool value = false;
      if (reader->PopBool(&value))
        result = new base::FundamentalValue(value);
      break;
    }
    case Message::INT16: {
      int16 value = 0;
      if (reader->PopInt16(&value))
        result = new base::FundamentalValue(value);
      break;
    }
    case Message::UINT16: {
      uint16 value = 0;
      if (reader->PopUint16(&value))
        result = new base::FundamentalValue(value);
      break;
    }
    case Message::INT32: {
      int32 value = 0;
      if (reader->PopInt32(&value))
        result = new base::FundamentalValue(value);
      break;
    }
    case Message::UINT32: {
      uint32 value = 0;
      if (reader->PopUint32(&value))
        result = new base::FundamentalValue(static_cast<double>(value));
      break;
    }
    case Message::INT64: {
      int64 value = 0;
      if (reader->PopInt64(&value)) {
        DLOG_IF(WARNING, !IsExactlyRepresentableByDouble(value)) <<
            value << " is not exactly representable by double";
        result = new base::FundamentalValue(static_cast<double>(value));
      }
      break;
    }
    case Message::UINT64: {
      uint64 value = 0;
      if (reader->PopUint64(&value)) {
        DLOG_IF(WARNING, !IsExactlyRepresentableByDouble(value)) <<
            value << " is not exactly representable by double";
        result = new base::FundamentalValue(static_cast<double>(value));
      }
      break;
    }
    case Message::DOUBLE: {
      double value = 0;
      if (reader->PopDouble(&value))
        result = new base::FundamentalValue(value);
      break;
    }
    case Message::STRING: {
      std::string value;
      if (reader->PopString(&value))
        result = new base::StringValue(value);
      break;
    }
    case Message::OBJECT_PATH: {
      ObjectPath value;
      if (reader->PopObjectPath(&value))
        result = new base::StringValue(value.value());
      break;
    }
    case Message::UNIX_FD: {
      // Cannot distinguish a file descriptor from an int
      NOTREACHED();
      break;
    }
    case Message::ARRAY: {
      MessageReader sub_reader(NULL);
      if (reader->PopArray(&sub_reader)) {
        // If the type of the array's element is DICT_ENTRY, create a
        // DictionaryValue, otherwise create a ListValue.
        if (sub_reader.GetDataType() == Message::DICT_ENTRY) {
          scoped_ptr<base::DictionaryValue> dictionary_value(
              new base::DictionaryValue);
          if (PopDictionaryEntries(&sub_reader, dictionary_value.get()))
            result = dictionary_value.release();
        } else {
          scoped_ptr<base::ListValue> list_value(new base::ListValue);
          if (PopListElements(&sub_reader, list_value.get()))
            result = list_value.release();
        }
      }
      break;
    }
    case Message::STRUCT: {
      MessageReader sub_reader(NULL);
      if (reader->PopStruct(&sub_reader)) {
        scoped_ptr<base::ListValue> list_value(new base::ListValue);
        if (PopListElements(&sub_reader, list_value.get()))
          result = list_value.release();
      }
      break;
    }
    case Message::DICT_ENTRY:
      // DICT_ENTRY must be popped as an element of an array.
      NOTREACHED();
      break;
    case Message::VARIANT: {
      MessageReader sub_reader(NULL);
      if (reader->PopVariant(&sub_reader))
        result = PopDataAsValue(&sub_reader);
      break;
    }
  }
  return result;
}

void AppendBasicTypeValueData(MessageWriter* writer, const base::Value& value) {
  switch (value.GetType()) {
    case base::Value::TYPE_BOOLEAN: {
      bool bool_value = false;
      bool success = value.GetAsBoolean(&bool_value);
      DCHECK(success);
      writer->AppendBool(bool_value);
      break;
    }
    case base::Value::TYPE_INTEGER: {
      int int_value = 0;
      bool success = value.GetAsInteger(&int_value);
      DCHECK(success);
      writer->AppendInt32(int_value);
      break;
    }
    case base::Value::TYPE_DOUBLE: {
      double double_value = 0;
      bool success = value.GetAsDouble(&double_value);
      DCHECK(success);
      writer->AppendDouble(double_value);
      break;
    }
    case base::Value::TYPE_STRING: {
      std::string string_value;
      bool success = value.GetAsString(&string_value);
      DCHECK(success);
      writer->AppendString(string_value);
      break;
    }
    default:
      DLOG(ERROR) << "Unexpected type " << value.GetType();
      break;
  }
}

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

void AppendValueData(MessageWriter* writer, const base::Value& value) {
  switch (value.GetType()) {
    case base::Value::TYPE_DICTIONARY: {
      const base::DictionaryValue* dictionary = NULL;
      value.GetAsDictionary(&dictionary);
      dbus::MessageWriter array_writer(NULL);
      writer->OpenArray("{sv}", &array_writer);
      for (base::DictionaryValue::Iterator iter(*dictionary);
           !iter.IsAtEnd(); iter.Advance()) {
        dbus::MessageWriter dict_entry_writer(NULL);
        array_writer.OpenDictEntry(&dict_entry_writer);
        dict_entry_writer.AppendString(iter.key());
        AppendValueDataAsVariant(&dict_entry_writer, iter.value());
        array_writer.CloseContainer(&dict_entry_writer);
      }
      writer->CloseContainer(&array_writer);
      break;
    }
    case base::Value::TYPE_LIST: {
      const base::ListValue* list = NULL;
      value.GetAsList(&list);
      dbus::MessageWriter array_writer(NULL);
      writer->OpenArray("v", &array_writer);
      for (base::ListValue::const_iterator iter = list->begin();
           iter != list->end(); ++iter) {
        const base::Value* value = *iter;
        AppendValueDataAsVariant(&array_writer, *value);
      }
      writer->CloseContainer(&array_writer);
      break;
    }
    case base::Value::TYPE_BOOLEAN:
    case base::Value::TYPE_INTEGER:
    case base::Value::TYPE_DOUBLE:
    case base::Value::TYPE_STRING:
      AppendBasicTypeValueData(writer, value);
      break;
    default:
      DLOG(ERROR) << "Unexpected type: " << value.GetType();
  }
}

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

}  // namespace dbus
