//
// Created by Ht on 2020/7/26.
//

#ifndef LIBDEVCPP_SOCKETHANDLERHOLDER_H
#define LIBDEVCPP_SOCKETHANDLERHOLDER_H

#include <jebase/config.h>
#include "ChannelOperator.h"

namespace jedge {

    using JsonSocketHandler = JE_API std::function<bool(ChannelOperator & opr, qlibc::QData & message)>;
    using JsonSocketRequestUDHandler = JE_API std::function<bool(ChannelOperator & opr, qlibc::QData & message, qlibc::QData * resp)>;

    using RegHandlers = JE_API std::vector<std::pair<std::regex, JsonSocketHandler>>;
    using UriHandlers = JE_API std::unordered_map<std::string, JsonSocketHandler>;

    class JE_API SocketHandlerHolder {
    protected:
        ChannelOperator& operator_;

        RegHandlers  reg_handlers_;
        UriHandlers  uri_handlers_;
        JsonSocketHandler* default_ = nullptr;
        JsonSocketHandler* unhandle_default_ = nullptr;
        std::mutex   mutex_;
        bool mb_print_err_ = false;

    public:
        explicit SocketHandlerHolder(ChannelOperator& opr) : operator_(opr) {}

        virtual ~SocketHandlerHolder() {
            clearDefaultHandler();
        };

        void clearDefaultHandler() {
            SINGLE_LOCK(mutex_);
            delete (default_);
            default_ = nullptr;
            delete (unhandle_default_);
            unhandle_default_ = nullptr;
        }

        void dispatchMessage(string& uri, qlibc::QData *msg);

        void DefaultHandler(const JsonSocketHandler& handler) {
            SINGLE_LOCK(mutex_);
            if(default_!=nullptr)
                delete default_;
            default_ = new JsonSocketHandler(handler);
        }

        void UnhandleHandler(const JsonSocketHandler& handler) {
            SINGLE_LOCK(mutex_);
            if(unhandle_default_!=nullptr)
                delete unhandle_default_;
            unhandle_default_ = new JsonSocketHandler(handler);
        }

        //添加特定uri的handler，优先级较高
        bool Uri(const string &uri, const JsonSocketHandler& handler){
            SINGLE_LOCK(mutex_);
            uri_handlers_.insert(std::make_pair(uri, handler));
            return true;
        };

        //添加模式uri的handler
        bool Regex(const string &pattern, const JsonSocketHandler& handler){
            SINGLE_LOCK(mutex_);
            reg_handlers_.push_back(std::make_pair(std::regex(pattern), handler));
            return true;
        };

        void clearRegex(const string &pattern = "") {
            SINGLE_LOCK(mutex_);
            if(pattern.empty())
                reg_handlers_.clear();
            else{
                std::smatch matches;
                for (auto handler = reg_handlers_.begin(); handler!=reg_handlers_.end(); handler++) {
                    if (!std::regex_match(pattern, matches, handler->first)) continue;
                    reg_handlers_.erase(handler);
                    break;
                }
            }
        }

        bool unhandled_Message(ChannelOperator &opr, qlibc::QData &msg);

        //是否打印错误信息
        void setPrintErrMsg(bool print);
    };

}

#endif //LIBDEVCPP_SOCKETHANDLERHOLDER_H
