// 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 "Collections.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());
    }

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

    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 asSerialized(String* output) const;

    virtual void writeJSON(StringBuilder* output) const;
    virtual std::unique_ptr<Value> clone() const;
    String serialize() 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;
    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;
    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}} SerializedValue : public Value {
public:
    static std::unique_ptr<SerializedValue> create(const String& value)
    {
        return std::unique_ptr<SerializedValue>(new SerializedValue(value));
    }

    bool asSerialized(String* output) const override;
    void writeJSON(StringBuilder* output) const override;
    std::unique_ptr<Value> clone() const override;

private:
    explicit SerializedValue(const String& value) : Value(TypeSerialized), m_serializedValue(value) { }

    String m_serializedValue;
};

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;
    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 = protocol::HashMap<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;
    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(); }

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

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

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