#pragma once

#include "ehs/EHS.h"
#include "ehs/Str.h"
#include "JsonBase.h"
#include "JsonObj.h"
#include "JsonArray.h"
#include "JsonBool.h"
#include "JsonNum.h"
#include "JsonStr.h"
#include "JsonVar.h"

namespace ehs
{
	class Json
	{
    private:
        JsonBase* value;

	public:
        virtual ~Json();

        Json();

        Json(const JsonBase& value);

        Json(const JsonObj& value);

        Json(const JsonArray& value);

        Json(const JsonBool& value);

        Json(const JsonNum& value);

        Json(const JsonStr& value);

        Json(const char* data, const UInt_64 size, const UInt_64 extra);

        Json(const Str_8& data, const UInt_64 extra);

		Json(Json&& json) noexcept;

        Json(const Json &json);

		Json& operator=(Json&& json) noexcept;

        Json& operator=(const Json& json);

        JsonBase* GetValue();

        JsonBase* RetrieveValue(const Str_8& access);

        Str_8 ToStr(const bool compact) const;

    private:
        static Vector<Str_8> ParseAccess(const Str_8& access);

        void ParseValue(JsonVar* var, const Char_8** begin, const Char_8* end, const UInt_64 extra);

        JsonVar ParseVar(const Char_8** begin, const Char_8* end, const UInt_64 extra);

        void ParseObject(JsonObj* obj, const Char_8** begin, const Char_8* end, const UInt_64 extra);

        void ParseArray(JsonArray* arr, const Char_8** begin, const Char_8* end, const UInt_64 extra);

        void Parse(const Str_8& data, const UInt_64 extra);
	};
}