// This file is generated by ValueConversions_h.template.

// Copyright 2016 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.

#ifndef {{"_".join(config.protocol.namespace)}}_ValueConversions_h
#define {{"_".join(config.protocol.namespace)}}_ValueConversions_h

//#include "ErrorSupport.h"
//#include "Forward.h"
//#include "Values.h"

{% for namespace in config.protocol.namespace %}
namespace {{namespace}} {
{% endfor %}

template<typename T>
struct ValueConversions {
    static std::unique_ptr<T> fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        return T::fromValue(value, errors);
    }

    static std::unique_ptr<protocol::Value> toValue(T* value)
    {
        return value->toValue();
    }

    static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<T>& value)
    {
        return value->toValue();
    }
};

template<>
struct ValueConversions<bool> {
    static bool fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        bool result = false;
        bool success = value ? value->asBoolean(&result) : false;
        if (!success)
            errors->AddError("boolean value expected");
        return result;
    }

    static std::unique_ptr<protocol::Value> toValue(bool value)
    {
        return FundamentalValue::create(value);
    }
};

template<>
struct ValueConversions<int> {
    static int fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        int result = 0;
        bool success = value ? value->asInteger(&result) : false;
        if (!success)
            errors->AddError("integer value expected");
        return result;
    }

    static std::unique_ptr<protocol::Value> toValue(int value)
    {
        return FundamentalValue::create(value);
    }
};

template<>
struct ValueConversions<double> {
    static double fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        double result = 0;
        bool success = value ? value->asDouble(&result) : false;
        if (!success)
            errors->AddError("double value expected");
        return result;
    }

    static std::unique_ptr<protocol::Value> toValue(double value)
    {
        return FundamentalValue::create(value);
    }
};

template<>
struct ValueConversions<String> {
    static String fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        String result;
        bool success = value ? value->asString(&result) : false;
        if (!success)
            errors->AddError("string value expected");
        return result;
    }

    static std::unique_ptr<protocol::Value> toValue(const String& value)
    {
        return StringValue::create(value);
    }
};

template<>
struct ValueConversions<Binary> {
    static Binary fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        if (!value ||
            (value->type() != Value::TypeBinary && value->type() != Value::TypeString)) {
            errors->AddError("Either string base64 or binary value expected");
            return Binary();
        }
        Binary binary;
        if (value->asBinary(&binary))
            return binary;
        String result;
        value->asString(&result);
        bool success;
        Binary out = Binary::fromBase64(result, &success);
        if (!success)
          errors->AddError("base64 decoding error");
        return out;
    }

    static std::unique_ptr<protocol::Value> toValue(const Binary& value)
    {
        return BinaryValue::create(value);
    }
};

template<typename T>
struct ValueConversions<std::vector<std::unique_ptr<T>>> {
    static std::unique_ptr<std::vector<std::unique_ptr<T>>> fromValue(protocol::Value* value, ErrorSupport* errors) {
        protocol::ListValue* array = ListValue::cast(value);
        if (!array) {
            errors->AddError("array expected");
            return nullptr;
        }
        errors->Push();
        std::unique_ptr<std::vector<std::unique_ptr<T>>> result(
            new std::vector<std::unique_ptr<T>>());
        result->reserve(array->size());
        for (size_t i = 0; i < array->size(); ++i) {
            errors->SetIndex(i);
            auto item = ValueConversions<T>::fromValue(array->at(i), errors);
            result->emplace_back(std::move(item));
        }
        errors->Pop();
        if (!errors->Errors().empty())
            return nullptr;
        return result;
    }

    static std::unique_ptr<protocol::ListValue> toValue(std::vector<std::unique_ptr<T>>* v)
    {
        std::unique_ptr<protocol::ListValue> result = ListValue::create();
        result->reserve(v->size());
        for (auto& item : *v)
            result->pushValue(ValueConversions<T>::toValue(item.get()));
        return result;
    }

};

template<typename T>
struct ValueConversions<std::vector<T>> {
    static std::unique_ptr<std::vector<T>> fromValue(protocol::Value* value, ErrorSupport* errors) {
        protocol::ListValue* array = ListValue::cast(value);
        if (!array) {
            errors->AddError("array expected");
            return nullptr;
        }
        errors->Push();
        std::unique_ptr<std::vector<T>> result(new std::vector<T>());
        result->reserve(array->size());
        for (size_t i = 0; i < array->size(); ++i) {
            errors->SetIndex(i);
            auto item = ValueConversions<T>::fromValue(array->at(i), errors);
            result->emplace_back(std::move(item));
        }
        errors->Pop();
        if (!errors->Errors().empty())
            return nullptr;
        return result;
    }

    static std::unique_ptr<protocol::ListValue> toValue(std::vector<T>* v)
    {
        std::unique_ptr<protocol::ListValue> result = ListValue::create();
        result->reserve(v->size());
        for (auto& item : *v)
            result->pushValue(ValueConversions<T>::toValue(item));
        return result;
    }
};

template<>
struct ValueConversions<Value> {
    static std::unique_ptr<Value> fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        bool success = !!value;
        if (!success) {
            errors->AddError("value expected");
            return nullptr;
        }
        return value->clone();
    }

    static std::unique_ptr<protocol::Value> toValue(Value* value)
    {
        return value->clone();
    }

    static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<Value>& value)
    {
        return value->clone();
    }
};

template<>
struct ValueConversions<DictionaryValue> {
    static std::unique_ptr<DictionaryValue> fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        bool success = value && value->type() == protocol::Value::TypeObject;
        if (!success)
            errors->AddError("object expected");
        return DictionaryValue::cast(value->clone());
    }

    static std::unique_ptr<protocol::Value> toValue(DictionaryValue* value)
    {
        return value->clone();
    }

    static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<DictionaryValue>& value)
    {
        return value->clone();
    }
};

template<>
struct ValueConversions<ListValue> {
    static std::unique_ptr<ListValue> fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        bool success = value && value->type() == protocol::Value::TypeArray;
        if (!success)
            errors->AddError("list expected");
        return ListValue::cast(value->clone());
    }

    static std::unique_ptr<protocol::Value> toValue(ListValue* value)
    {
        return value->clone();
    }

    static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<ListValue>& value)
    {
        return value->clone();
    }
};

template<typename T> struct ValueTypeConverter {
  static std::unique_ptr<T> FromValue(const protocol::Value& value) {
    std::vector<uint8_t> bytes;
    value.AppendSerialized(&bytes);
    return T::FromBinary(bytes.data(), bytes.size());
  }

  static std::unique_ptr<protocol::DictionaryValue> ToValue(const T& obj) {
    std::vector<uint8_t> bytes;
    obj.AppendSerialized(&bytes);
    auto result = Value::parseBinary(bytes.data(), bytes.size());
    return DictionaryValue::cast(std::move(result));
  }
};

{% for namespace in config.protocol.namespace %}
} // namespace {{namespace}}
{% endfor %}

namespace {{config.crdtp.namespace}} {

template<typename T>
struct ProtocolTypeTraits<T,
     typename std::enable_if<std::is_base_of<{{"::".join(config.protocol.namespace)}}::Value, T>::value>::type> {
  static void Serialize(const {{"::".join(config.protocol.namespace)}}::Value& value, std::vector<uint8_t>* bytes) {
    value.AppendSerialized(bytes);
  }
};

template <>
struct ProtocolTypeTraits<std::unique_ptr<{{"::".join(config.protocol.namespace)}}::Value>> {
  static bool Deserialize(DeserializerState* state, std::unique_ptr<{{"::".join(config.protocol.namespace)}}::Value>* value);
  static void Serialize(const std::unique_ptr<{{"::".join(config.protocol.namespace)}}::Value>& value, std::vector<uint8_t>* bytes);
};

template <>
struct ProtocolTypeTraits<std::unique_ptr<{{"::".join(config.protocol.namespace)}}::DictionaryValue>> {
  static bool Deserialize(DeserializerState* state, std::unique_ptr<{{"::".join(config.protocol.namespace)}}::DictionaryValue>* value);
  static void Serialize(const std::unique_ptr<{{"::".join(config.protocol.namespace)}}::DictionaryValue>& value, std::vector<uint8_t>* bytes);
};

// TODO(caseq): get rid of it, it's just a DictionaryValue really.
template <>
struct ProtocolTypeTraits<std::unique_ptr<{{"::".join(config.protocol.namespace)}}::Object>> {
  static bool Deserialize(DeserializerState* state, std::unique_ptr<{{"::".join(config.protocol.namespace)}}::Object>* value);
  static void Serialize(const std::unique_ptr<{{"::".join(config.protocol.namespace)}}::Object>& value, std::vector<uint8_t>* bytes);
};

template<>
struct ProtocolTypeTraits<{{"::".join(config.protocol.namespace)}}::Object> {
  static void Serialize(const {{"::".join(config.protocol.namespace)}}::Object& value, std::vector<uint8_t>* bytes) {
    value.AppendSerialized(bytes);
  }
};

}  // namespace {{config.crdtp.namespace}}

#endif // !defined({{"_".join(config.protocol.namespace)}}_ValueConversions_h)
