#pragma once
#include <map>
#include <xs/xs.h>
#include <panda/string.h>
#include <panda/uri/URI.h>

namespace xs { namespace uri {

using panda::string;
using panda::uri::URI;

typedef URI URIx;

class XSURI {
public:
    URI*             uri;
    mutable SV*      query_cache;
    mutable uint32_t query_cache_rev;

    XSURI (URI* uri) : uri(uri), query_cache(NULL), query_cache_rev(0) {
        uri->retain();
    }

    void sync_query_hv (pTHX) const;

    SV* query_hv (pTHX) const {
        if (!query_cache || query_cache_rev != uri->query().rev) sync_query_hv(aTHX);
        return query_cache;
    }

    ~XSURI () {
        dTHX;
        if (query_cache) SvREFCNT_dec(query_cache);
        uri->release();
    }

    static void register_perl_scheme (pTHX_ const char* scheme, const char* perl_class);
    static SV*  get_perl_class       (pTHX_ const URI* uri);

    static void add_query_args (pTHX_ URI* uri, SV** sp, I32 items, bool replace = false);
    static void add_query_hv   (pTHX_ URI* uri, HV*, bool replace = false);
    static void add_param      (pTHX_ URI* uri, string key, SV* val, bool replace = false);

private:
    typedef std::map<uint64_t, SV*> UriClassMap;
    static UriClassMap uri_class_map;

    XSURI (const XSURI& s) {}
    XSURI& operator= (const XSURI& s) { return *this; }
};

}}
