#include <ev++.h>
#include <log.h>
#include <net-service.h>
#include "db_api/CDBSingletonDefine.h"
#include "websocket/wsClientMgr.h"
#include "websocket/wsTimerThread.h"

#include "card.h"
#include "ant.h"
#include "area.h"
#include "card_path.h"
#include "landmark.h"
#include "special_area.h"
#include "mine.h"
#include "event.h"
#include"module_service/module_mgr.h"

#include <config_file.h>
#include "three_rates.h"
#include "mine_business.h"
#include "ya_setting.h"
#include "websocket/web_connect.h"
#include "forbid_staff_down_mine.h"
#include "bulletin_broad_show.h"

config_file config;
void handlereader(uint32_t readerid,bool duration,uint32_t t)
{}
//三率模块中告警回调
void Handle_ThreeRates_Event_Callback(const int evType, const int evId, uint64_t id
                                      , double limitVal, double curVal, bool bFalg)
{
    if (evId >= EVENT_TYPE::CARD_EVENT_COUNT_MAX  || evType > OBJECT_TYPE::OT_CARD)
    {
        return ;
    }
    event_tool::instance()->handle_event((OBJECT_TYPE)evType,(EVENT_TYPE)evId,id,limitVal,curVal,bFalg);
}

struct Init_Setting
{
    void init()
    {
        three_rates_flag=config.get("service.three_rates_flag",0);
        YADB::_DB_POOL_SETTING_ DBSetting;
        DBSetting.Host = config.get("db.host","127.0.0.1");
        DBSetting.User = config.get("db.user","root");
        DBSetting.PWD = config.get("db.passwd","123456");
        DBSetting.DBName = config.get("db.dbname","yaxt");
        DBSetting.CharSet = config.get("db.charset","utf8");
        DBSetting.TimeOut = config.get("db.conn_timeout",5);
        DBSetting.PoolSize = config.get("db.pool_size",30);
        DBSetting.Port = config.get("db.port",3306);
        if(!_mysql_init(DBSetting))
        {
            std_info("连接DB[%s:%s] 失败,采集服务器无法启动!",DBSetting.Host.c_str(),DBSetting.User.c_str());
            log_warn("连接DB[%s:%s] 失败,采集服务器无法启动!",DBSetting.Host.c_str(),DBSetting.User.c_str());
            exit(0);
        }
        log_info("数据库线程池创建成功");

        std::string url=config.get("service.websocket_url","ws://127.0.0.1:8086");
        std::string url_2=config.get("service.websocket_url_bak","");
        int32_t send_interval =config.get("service.interval_send_json_postion",1);
        std_info("json_interval:%d,[%s]",send_interval,url.c_str());
        std::vector<std::string> url_list;
        url_list.push_back(url);
        if(!url_2.empty())url_list.push_back(url_2);
        if(!wsClientMgr_init(url_list,send_interval))
        {
            std_info("连接webServer[%s] 失败,采集服务器无法启动!",url.c_str());
            log_warn("连接webServer[%s] 失败!",url.c_str());
        }
		CYaSetting::Init_sys_setting();
        bulletin_broad_show::inst()->OnInit(&config);

        sit_list::instance()->load_from_db();
        card_list::instance()->init_card_from_db();
        area_list::instance()->init_from_db();
        forbid_staff_down_mine::instance()->init_forbid_staff();
        //point pt(3348,100);
        //int id = area_list::instance()->get_area(pt)->id();
        //std_info("test area:%d",id);
        Landmark_list::instance()->init_from_db();
        //auto a = Landmark_list::instance()->get(5,id,pt);
        //std_info("test landmark:id:%d,dir:%d,dis:%.2f",std::get<0>(a),std::get<1>(a),std::get<2>(a));
        special_area_list::instance()->init_from_db();
        //auto s = special_area_list::instance()->get_special_id(1013,point(4727,-254),2);
        //std_info("test special_area:%d",s);
		mine_business::inst()->load();
        event_list::instance()->load_his_data_from_db();
        card_list::instance()->load_his_card_postion_from_db();
        if(three_rates_flag){
            db_para dp;	
            dp.Host=DBSetting.Host;
            dp.User=DBSetting.User;
            dp.PWD=DBSetting.PWD ;
            dp.DBName=DBSetting.DBName;
            dp.CharSet=DBSetting.CharSet ;
            dp.TimeOut=DBSetting.TimeOut;
            dp.PoolSize=DBSetting.PoolSize;
		    init_three_rates(dp);
        }


        log_info("Init_Setting::init  Success. \n" );

    }

	void init_three_rates(const db_para& dbs)
	{
		log_info("init three_rates ...................");
		init_para ip;
		ip.send_pt = handlereader;
		ip.driving_face_alarm = Handle_ThreeRates_Event_Callback;
		three_rates::get_instance()->init(ip,dbs);
		three_rates::get_instance()->start();
        std_info("加载三率模块成功");
	}

    bool _mysql_init(YADB::_DB_POOL_SETTING_ &dps)
    {
        std::string szError = "";
		bool flag = true;
        //创建连接池
        if ( !sDBConnPool.Create( dps, szError ) )
        {
            log_error("数据库线程池创建失败,Err=%s", szError.c_str());
            std_error("数据库线程池创建失败,Err=%s", szError.c_str());
			flag = false;
        }
		return flag;
    }

    bool wsClientMgr_init(const std::vector<std::string>&uri_list,int32_t st)
    {
        std::map<std::string, YA::MSG_HANDLE_FUNC_TYPE> MsgFuncList;
        module_mgr::init(config, MsgFuncList);

        web_connect::init(uri_list, st, MsgFuncList);

        return web_connect::connect();
    }
};


void cleanup()
{
    module_mgr::stop();
    web_connect::close();
}

void usage(char ** argv)
{
    std::string cmd(argv[1]);
    if(cmd=="--help" || cmd == "-H")
    {
        printf("用法:yals [选项]文件...\n");
        printf("选项:\n");
        printf("--help				显示此帮助说明\n");
        printf("-v|--version		显示采集程序版本信息\n");
    }
    else if(cmd == "--version" || cmd == "-v")
    {
        printf("yals (采集程序) 2.0.0 build 11\n");
    }
    else
    {
        printf("Unknown option:%s\n",cmd.c_str());
        printf( "usage:yals [--version][--help][-v][-H]\n");
    }


}

int main(int argc ,char * argv[])
{
    if(argc >1)
    {
        usage(argv);
        return 0;
    }

    log_init("../etc/log.ini");
    if(config.open("../etc/config.ini"))
        return -1;

    Init_Setting is;
    is.init();

    module_mgr::start();
    web_connect::start_beatheart_monitor();
    atexit(&cleanup);

    net_service mh;
    int port=config.get("service.port",4000);

    log_info("service_handle::instance(&mh)->run(%d)",port);
    std_info("service_handle::instance(&mh)->run(%d)",port);

    service_handle::instance(&mh)->run(port);
    
    sDBConnPool.Close();

    sleep(1);
    printf("YA-SERV Server Exit ...\n");

    return 0;
}