#ifndef _QmfEngineConsoleEngineImpl_
#define _QmfEngineConsoleEngineImpl_

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "qmf/engine/Console.h"
#include "qmf/engine/MessageImpl.h"
#include "qmf/engine/SchemaImpl.h"
#include "qmf/engine/Typecode.h"
#include "qmf/engine/ObjectImpl.h"
#include "qmf/engine/ObjectIdImpl.h"
#include "qmf/engine/QueryImpl.h"
#include "qmf/engine/ValueImpl.h"
#include "qmf/engine/Protocol.h"
#include "qmf/engine/SequenceManager.h"
#include "qmf/engine/BrokerProxyImpl.h"
#include <qpid/framing/Buffer.h>
#include <qpid/framing/Uuid.h>
#include <qpid/framing/FieldTable.h>
#include <qpid/framing/FieldValue.h>
#include <qpid/sys/Mutex.h>
#include <qpid/sys/Time.h>
#include <qpid/sys/SystemInfo.h>
#include <string.h>
#include <string>
#include <deque>
#include <map>
#include <vector>
#include <iostream>
#include <fstream>
#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>

namespace qmf {
namespace engine {

    struct ConsoleEventImpl {
        typedef boost::shared_ptr<ConsoleEventImpl> Ptr;
        ConsoleEvent::EventKind kind;
        boost::shared_ptr<AgentProxy> agent;
        std::string name;
        const SchemaClassKey* classKey;
        boost::shared_ptr<Object> object;
        void* context;
        boost::shared_ptr<Event> event;
        uint64_t timestamp;
        bool hasProps;
        bool hasStats;

        ConsoleEventImpl(ConsoleEvent::EventKind k) :
        kind(k), classKey(0), context(0), timestamp(0) {}
        ~ConsoleEventImpl() {}
        ConsoleEvent copy();
    };

    class ConsoleImpl : public boost::noncopyable {
    public:
        ConsoleImpl(const ConsoleSettings& settings = ConsoleSettings());
        ~ConsoleImpl();

        bool getEvent(ConsoleEvent& event) const;
        void popEvent();

        void addConnection(BrokerProxy& broker, void* context);
        void delConnection(BrokerProxy& broker);

        uint32_t packageCount() const;
        const std::string& getPackageName(uint32_t idx) const;

        uint32_t classCount(const char* packageName) const;
        const SchemaClassKey* getClass(const char* packageName, uint32_t idx) const;

        ClassKind getClassKind(const SchemaClassKey* key) const;
        const SchemaObjectClass* getObjectClass(const SchemaClassKey* key) const;
        const SchemaEventClass* getEventClass(const SchemaClassKey* key) const;

        void bindPackage(const char* packageName);
        void bindClass(const SchemaClassKey* key);
        void bindClass(const char* packageName, const char* className);
        void bindEvent(const SchemaClassKey* key);
        void bindEvent(const char* packageName, const char* eventName);

        /*
        void startSync(const Query& query, void* context, SyncQuery& sync);
        void touchSync(SyncQuery& sync);
        void endSync(SyncQuery& sync);
        */

    private:
        friend class BrokerProxyImpl;
        friend struct StaticContext;
        const ConsoleSettings& settings;
        mutable qpid::sys::Mutex lock;
        std::deque<ConsoleEventImpl::Ptr> eventQueue;
        std::vector<BrokerProxyImpl*> brokerList;
        std::vector<std::pair<std::string, std::string> > bindingList; // exchange/key (empty exchange => QMF_EXCHANGE)

        // Declare a compare class for the class maps that compares the dereferenced
        // class key pointers.  The default behavior would be to compare the pointer
        // addresses themselves.
        struct KeyCompare {
            bool operator()(const SchemaClassKey* left, const SchemaClassKey* right) const {
                return *left < *right;
            }
        };

        typedef std::map<const SchemaClassKey*, SchemaObjectClass*, KeyCompare> ObjectClassList;
        typedef std::map<const SchemaClassKey*, SchemaEventClass*, KeyCompare> EventClassList;
        typedef std::map<std::string, std::pair<ObjectClassList, EventClassList> > PackageList;

        PackageList packages;

        void learnPackage(const std::string& packageName);
        void learnClass(SchemaObjectClass* cls);
        void learnClass(SchemaEventClass* cls);
        bool haveClass(const SchemaClassKey* key) const;
        SchemaObjectClass* getSchema(const SchemaClassKey* key) const;

        void eventAgentAdded(boost::shared_ptr<AgentProxy> agent);
        void eventAgentDeleted(boost::shared_ptr<AgentProxy> agent);
        void eventNewPackage(const std::string& packageName);
        void eventNewClass(const SchemaClassKey* key);
        void eventObjectUpdate(ObjectPtr object, bool prop, bool stat);
        void eventAgentHeartbeat(boost::shared_ptr<AgentProxy> agent, uint64_t timestamp);
        void eventEventReceived(boost::shared_ptr<Event> event);
    };
}
}

#endif

