#pragma once

#include <util/generic/string.h>
#include <library/cpp/json/writer/json_value.h>

namespace NRTYCluster {
    class TSlotData {
    private:
        mutable TString DC;
        mutable TString DCAlias;
        mutable TString RealHost;
        TString FullHostName;
        TString ShortHostName;
        TString FullSlot;
        TString ShortSlot;

        void Initialize(const TString& host, ui32 port);

    public:
        ui32 Port = 0;

        TSlotData() {
        }

        TSlotData(const TString& host, ui32 port) {
            Initialize(host, port);
        }

        const TString& FullHost() const {
            return FullHostName;
        }

        TString ShortHost() const {
            return ShortHostName;
        }

        TString ShortSlotName() const {
            return ShortSlot;
        }

        TString FullSlotName() const {
            return FullSlot;
        }

        bool operator < (const TSlotData& item) const {
            return ShortSlot < item.ShortSlot;
        }

        bool operator == (const TSlotData& item) const {
            return ShortSlot == item.ShortSlot;
        }

        TString GetDC() const;
        bool SetDC(const TString& value) const;
        TString GetDCAlias(bool skipError = true, const TString& aliasIfAbsent="") const;

        TString GetRealHost() const;
        bool SetRealHost(const TString& value) const;

        static bool Parse(TStringBuf slotName, TSlotData& result);
        static bool ParseAsEndpointSet(TStringBuf slotName, TSlotData& result);

        ui32 ControllerPort() const {
            return Port + 3;
        }

        ui32 IndexPort() const {
            return Port + 2;
        }

        bool Deserialize(const NJson::TJsonValue& json) {
            if (!json.IsMap())
                return false;

            const NJson::TJsonValue& jsonPort = json["port"];
            const NJson::TJsonValue& jsonHost = json["host"];
            const NJson::TJsonValue& jsonDC = json["dc"];
            const NJson::TJsonValue& jsonDCAlias = json["dc_alias"];
            if (!jsonPort.IsInteger() || !jsonHost.IsString() || !jsonDC.IsString() || !jsonDCAlias.IsString())
                return false;
            Initialize(jsonHost.GetString(), jsonPort.GetInteger());
            DC = jsonDC.GetString();
            DCAlias = jsonDCAlias.GetString();
            return true;
        }

        NJson::TJsonValue Serialize() const {
            NJson::TJsonValue result(NJson::JSON_MAP);
            result["port"] = Port;
            result["host"] = FullHostName;
            result["dc"] = DC;
            result["dc_alias"] = DCAlias;
            return result;
        }

    };
}
