//
//  MediaForwardService.cpp
//
//  Created by 杨净 on 2018/3/20.
//  Copyright © 2018年 杨净. All rights reserved.
//
//  email: 1026397500@qq.com
//

// #include "WebSocket.h"
// #include "Rtp808.h"
// #include "MediaInfo.h"
#include "Rtp808Service.h"
#include "MediaInfoService.h"
#include "MediaForwardService.h"
// #include "ZWRedisTool.h"
#include "MediaWebSocketService.h"
#include "MediaClientService.h"
// #include "MediaRtmpService.h"
#include "ClientManager.h"
#include "MediaF3Protocol.h"
#include "ZWRoom.h"
#include "ZWForwardEpoll.h"

namespace mfs
{
    static void testlog(){
        for (size_t i = 0; i < 1; i++)
        {
            LOG_DEBUG << "TEST LOG  ----------------------------- " << LOG_ENDL;
        }
    }

    int MediaForwardService::InitializeAutomationTask(uvw::Loop &loop)
    {
        LOG_DEBUG<<"InitializeAutomationTask"<<LOG_ENDL;
        // timeout timer
        std::shared_ptr<uvw::TimerHandle> timer = loop.resource<uvw::TimerHandle>();
        timer->on<uvw::ErrorEvent>([](const auto &event, auto &handle){
            LOG_ERROR <<"timeout timer error("<<event.name()<<"):"<<event.what()<<LOG_ENDL;
        });
        timer->on<uvw::TimerEvent>([this](const auto &, auto &handle){
            // 超时检测
            Rtp808Service::Instance(_rtpPort)->CheckAllTimeout();
            Rtp808Service::Instance(_rtpybPort)->CheckAllTimeout();
            MediaWebSocketService::Instance()->CheckAllTimeout();
            MediaClientService::Instance()->CheckAllTimeout();
            // MediaRtmpService::Instance()->CheckAllTimeout();
            // ClientManager::Instance()->CheckAllTimeout();
            
            // redis连接
            // ZWRedisTool::RedisTool()->checkConnect();

            // testlog();
        });
        timer->unreference();
        timer->start(uvw::TimerHandle::Time{5000}, uvw::TimerHandle::Time{500});

        if (AppSetting::Instance()->enableSocket)
        {
            // f3 heartbeat
            std::shared_ptr<uvw::TimerHandle> timerf3 = loop.resource<uvw::TimerHandle>();
            timerf3->on<uvw::ErrorEvent>([](const auto &event, auto &handle){
                LOG_ERROR <<"f3 heartbeat error("<<event.name()<<"):"<<event.what()<<LOG_ENDL;
            });
            timerf3->on<uvw::TimerEvent>([this](const auto &, auto &handle){
                // LOG_DEBUG<<"MediaF3Protocol::Heartbeat"<<LOG_ENDL;
                MediaF3Protocol::Heartbeat();
                // 日志分文件
                autoLogSubpackage();
            });
            timerf3->unreference();
            timerf3->start(uvw::TimerHandle::Time{0}, uvw::TimerHandle::Time{1000*60*2});
        }
        
        // zoom check
        std::shared_ptr<uvw::TimerHandle> timerZoom = loop.resource<uvw::TimerHandle>();
        timerZoom->on<uvw::ErrorEvent>([](const auto &event, auto &handle){
            LOG_ERROR <<"zoom chekc error("<<event.name()<<"):"<<event.what()<<LOG_ENDL;
        });
        timerZoom->on<uvw::TimerEvent>([this](const auto &, auto &handle){
            ZWRoom::checkRooms();
        });
        timerZoom->unreference();
        timerZoom->start(uvw::TimerHandle::Time{0}, uvw::TimerHandle::Time{250});
        
        // redis
        // ZWRedisTool::RedisTool()->SetUVLoop(loop.raw());
        // FORWORT_ASSERT_RETURN_LOG_MSG(ZWRedisTool::RedisTool()->connectRedis()==0, "Failed to connect <redis>");

        return 0;
    }
    
int MediaForwardService::init()
{
    LOG_DEBUG<<"MediaForwardService:web port="<<_websocketPort<<",info port="<<_videoInfoPort<<",rtp port="<<_rtpPort<<",app port="<<_appPort<<".rtmp port="<< _rtmpPort <<LOG_ENDL;
    
    auto loop = uvw::Loop::getDefault();
    
    // task
    InitializeAutomationTask(*loop);
    // uvw
    MediaInfoService::SetupOnce(_videoInfoPort, loop);
    MediaInfoService::Instance()->Init();
        
    auto tempName = _type+"_RTP";
    Rtp808Service::SetupOnce(tempName, _rtpPort, loop);
    Rtp808Service::Instance(_rtpPort)->Init();

    tempName = _type+"_RTPYB";
    Rtp808Service::SetupOnce(tempName, _rtpybPort, loop);
    Rtp808Service::Instance(_rtpybPort)->Init();
    Rtp808Service::Instance(_rtpybPort)->isYuebiao(true);

    tempName = _type+"_WEB";
    MediaWebSocketService::SetupOnce(tempName, _websocketPort, loop);
    MediaWebSocketService::Instance()->Init();
    
    tempName = _type+"_APP";
    MediaClientService::SetupOnce(tempName, _appPort, loop);
    MediaClientService::Instance()->Init();
    
    // tempName = _type+"_RTMP";
    // MediaRtmpService::SetupOnce(tempName, _rtmpPort, loop);
    // MediaRtmpService::Instance()->Init();

    MediaF3Protocol::SetClientID(_type);

    ClientManager::SetupOnce(loop);

    if (_type == "Playback")
    {
        ZWRoom::setPlayback(true);
    }
    if (_type == "Talkback")
    {
        ZWRoom::setIsTalkback(true);
    }
    
    if(AppSetting::Instance()->EpollThreadCount>0){
        ZWForwardEpoll::instance()->run(AppSetting::Instance()->EpollThreadCount);
    }

    loop->run();

    return -1;
}


int MediaForwardService::start()
{
    Log::setCurrentLevel(LogLevel(AppSetting::Instance()->logLevel));
    int serverStatus = init();
    if (serverStatus<0)
    {
    }
    

    return serverStatus;
}

}