//
// Created by pgess on 3/14/15.
//

#ifndef _XREATE_CONTAINERSQUERY_H_
#define _XREATE_CONTAINERSQUERY_H_


#include "passmanager.h"
#include "clasplayer.h"

#include <boost/variant.hpp>

namespace xreate {
namespace containers {

    enum ImplementationType {SOLID,  ON_THE_FLY, LINKED_LIST};

    template<ImplementationType I>
    struct ImplementationRec;

    template<>
    struct ImplementationRec<SOLID> {
        size_t size;
    };

    template<>
    struct ImplementationRec<ON_THE_FLY>{
        Symbol source;
    };

    struct Implementation;
    struct ImplementationLinkedList {
        bool flagIsValid;
        std::string fieldPointer;
        Expression terminator;

        ImplementationLinkedList(const Symbol& source);
        operator bool() const;
        Implementation getImplementationData() const;

    private:
        Symbol s;
    };

    struct Implementation {
        typedef boost::variant<ImplementationRec<SOLID>, ImplementationRec<ON_THE_FLY>> Variant;
        const ImplementationType  impl;
        Variant data;

        static Implementation create(const Symbol &var);
        static Implementation create(const Symbol& var, const std::string &implSerialized);
        static Implementation create(const Symbol& var, const Implementation& proto);

        template<ImplementationType I>
        const ImplementationRec<I>& extract() const{
            const ImplementationRec<I>& rec = boost::get<ImplementationRec<I>>(data);
            return rec;
        }
    };

    class Query : public xreate::IQuery {
    public:
        static  Implementation queryImplementation(xreate::Symbol const &s);
        void init(ClaspLayer* clasp);

        Query();
        ~Query(){}
    private:
        bool flagIsDataLoaded = false;
        PassManager *man;
    };


}

     template<>
    struct AttachmentsDict<containers::Implementation> {
        typedef containers::Implementation Data;
        static const unsigned int key = 1;
    };
}

#endif //_XREATE_CONTAINERSQUERY_H_
