// This file is generated by Values_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)}}_Values_h
#define {{"_".join(config.protocol.namespace)}}_Values_h

//#include "Allocator.h"
//#include "Forward.h"

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

class ListValue;
class DictionaryValue;
class Value;

class {{config.lib.export_macro}} Value : public Serializable {
    PROTOCOL_DISALLOW_COPY(Value);
public:
    virtual ~Value() override { }

    static std::unique_ptr<Value> null()
    {
        return std::unique_ptr<Value>(new Value());
    }

    static std::unique_ptr<Value> parseBinary(const uint8_t* data, size_t size);

    enum ValueType {
        TypeNull = 0,
        TypeBoolean,
        TypeInteger,
        TypeDouble,
        TypeString,
        TypeBinary,
        TypeObject,
        TypeArray,
        TypeSerialized,
        TypeImported
    };

    ValueType type() const { return m_type; }

    bool isNull() const { return m_type == TypeNull; }

    virtual bool asBoolean(bool* output) const;
    virtual bool asDouble(double* output) const;
    virtual bool asInteger(int* output) const;
    virtual bool asString(String* output) const;
    virtual bool asBinary(Binary* output) const;

    virtual void writeJSON(StringBuilder* output) const;
    virtual void writeBinary(std::vector<uint8_t>* bytes) const;
    virtual std::unique_ptr<Value> clone() const;
    String toJSONString() const;
    String serializeToJSON() override;
    std::vector<uint8_t> serializeToBinary() override;

protected:
    Value() : m_type(TypeNull) { }
    explicit Value(ValueType type) : m_type(type) { }

private:
    friend class DictionaryValue;
    friend class ListValue;

    ValueType m_type;
};

class {{config.lib.export_macro}} FundamentalValue : public Value {
public:
    static std::unique_ptr<FundamentalValue> create(bool value)
    {
        return std::unique_ptr<FundamentalValue>(new FundamentalValue(value));
    }

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

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

    bool asBoolean(bool* output) const override;
    bool asDouble(double* output) const override;
    bool asInteger(int* output) const override;
    void writeJSON(StringBuilder* output) const override;
    void writeBinary(std::vector<uint8_t>* bytes) const override;
    std::unique_ptr<Value> clone() const override;

private:
    explicit FundamentalValue(bool value) : Value(TypeBoolean), m_boolValue(value) { }
    explicit FundamentalValue(int value) : Value(TypeInteger), m_integerValue(value) { }
    explicit FundamentalValue(double value) : Value(TypeDouble), m_doubleValue(value) { }

    union {
        bool m_boolValue;
        double m_doubleValue;
        int m_integerValue;
    };
};

class {{config.lib.export_macro}} StringValue : public Value {
public:
    static std::unique_ptr<StringValue> create(const String& value)
    {
        return std::unique_ptr<StringValue>(new StringValue(value));
    }

    static std::unique_ptr<StringValue> create(const char* value)
    {
        return std::unique_ptr<StringValue>(new StringValue(value));
    }

    bool asString(String* output) const override;
    void writeJSON(StringBuilder* output) const override;
    void writeBinary(std::vector<uint8_t>* bytes) const override;
    std::unique_ptr<Value> clone() const override;

private:
    explicit StringValue(const String& value) : Value(TypeString), m_stringValue(value) { }
    explicit StringValue(const char* value) : Value(TypeString), m_stringValue(value) { }

    String m_stringValue;
};

class {{config.lib.export_macro}} BinaryValue : public Value {
public:
    static std::unique_ptr<BinaryValue> create(const Binary& value)
    {
        return std::unique_ptr<BinaryValue>(new BinaryValue(value));
    }

    bool asBinary(Binary* output) const override;
    void writeJSON(StringBuilder* output) const override;
    void writeBinary(std::vector<uint8_t>* bytes) const override;
    std::unique_ptr<Value> clone() const override;

private:
    explicit BinaryValue(const Binary& value) : Value(TypeBinary), m_binaryValue(value) { }

    Binary m_binaryValue;
};

class {{config.lib.export_macro}} SerializedValue : public Value {
public:
    static std::unique_ptr<SerializedValue> fromJSON(const String& value)
    {
        return std::unique_ptr<SerializedValue>(new SerializedValue(value));
    }

    static std::unique_ptr<SerializedValue> fromBinary(std::vector<uint8_t> value)
    {
        return std::unique_ptr<SerializedValue>(new SerializedValue(std::move(value)));
    }

    void writeJSON(StringBuilder* output) const override;
    void writeBinary(std::vector<uint8_t>* bytes) const override;
    std::unique_ptr<Value> clone() const override;

private:
    explicit SerializedValue(const String& json) : Value(TypeSerialized), m_serializedJSON(json) { }
    explicit SerializedValue(std::vector<uint8_t> binary) : Value(TypeSerialized), m_serializedBinary(std::move(binary)) { }
    SerializedValue(const String& json, const std::vector<uint8_t>& binary)
        : Value(TypeSerialized), m_serializedJSON(json), m_serializedBinary(binary) { }
    String m_serializedJSON;
    std::vector<uint8_t> m_serializedBinary;
};

class {{config.lib.export_macro}} DictionaryValue : public Value {
public:
    using Entry = std::pair<String, Value*>;
    static std::unique_ptr<DictionaryValue> create()
    {
        return std::unique_ptr<DictionaryValue>(new DictionaryValue());
    }

    static DictionaryValue* cast(Value* value)
    {
        if (!value || value->type() != TypeObject)
            return nullptr;
        return static_cast<DictionaryValue*>(value);
    }

    static std::unique_ptr<DictionaryValue> cast(std::unique_ptr<Value> value)
    {
        return std::unique_ptr<DictionaryValue>(DictionaryValue::cast(value.release()));
    }

    void writeJSON(StringBuilder* output) const override;
    void writeBinary(std::vector<uint8_t>* bytes) const override;
    std::unique_ptr<Value> clone() const override;

    size_t size() const { return m_data.size(); }

    void setBoolean(const String& name, bool);
    void setInteger(const String& name, int);
    void setDouble(const String& name, double);
    void setString(const String& name, const String&);
    void setValue(const String& name, std::unique_ptr<Value>);
    void setObject(const String& name, std::unique_ptr<DictionaryValue>);
    void setArray(const String& name, std::unique_ptr<ListValue>);

    bool getBoolean(const String& name, bool* output) const;
    bool getInteger(const String& name, int* output) const;
    bool getDouble(const String& name, double* output) const;
    bool getString(const String& name, String* output) const;

    DictionaryValue* getObject(const String& name) const;
    ListValue* getArray(const String& name) const;
    Value* get(const String& name) const;
    Entry at(size_t index) const;

    bool booleanProperty(const String& name, bool defaultValue) const;
    int integerProperty(const String& name, int defaultValue) const;
    double doubleProperty(const String& name, double defaultValue) const;
    void remove(const String& name);

    ~DictionaryValue() override;

private:
    DictionaryValue();
    template<typename T>
    void set(const String& key, std::unique_ptr<T>& value)
    {
        DCHECK(value);
        bool isNew = m_data.find(key) == m_data.end();
        m_data[key] = std::move(value);
        if (isNew)
            m_order.push_back(key);
    }

    using Dictionary = std::unordered_map<String, std::unique_ptr<Value>>;
    Dictionary m_data;
    std::vector<String> m_order;
};

class {{config.lib.export_macro}} ListValue : public Value {
public:
    static std::unique_ptr<ListValue> create()
    {
        return std::unique_ptr<ListValue>(new ListValue());
    }

    static ListValue* cast(Value* value)
    {
        if (!value || value->type() != TypeArray)
            return nullptr;
        return static_cast<ListValue*>(value);
    }

    static std::unique_ptr<ListValue> cast(std::unique_ptr<Value> value)
    {
        return std::unique_ptr<ListValue>(ListValue::cast(value.release()));
    }

    ~ListValue() override;

    void writeJSON(StringBuilder* output) const override;
    void writeBinary(std::vector<uint8_t>* bytes) const override;
    std::unique_ptr<Value> clone() const override;

    void pushValue(std::unique_ptr<Value>);

    Value* at(size_t index);
    size_t size() const { return m_data.size(); }
    void reserve(size_t capacity) { m_data.reserve(capacity); }

private:
    ListValue();
    std::vector<std::unique_ptr<Value>> m_data;
};

void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst);
void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst);

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

#endif // {{"_".join(config.protocol.namespace)}}_Values_h
