#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 EHS_LIB_IO Json final
	{
    private:
        JsonBase *value;

	public:
		~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, UInt_64 size, UInt_64 extra);

        Json(const Str_8 &data, 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(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, UInt_64 extra);

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

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

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

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