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

#include "MediaForwardService.h"
#include "backtrace.h"
#include "AppSetting.h"

namespace 
{


std::map<pid_t, int> pidIndexMap;

// 信号处理
void signalCallback(int signal)
{
	LOG_ERROR << "SignalCallback: " << strsignal(signal) << " " << signal << LOG_ENDL;
    if(signal == SIGCHLD)
    {
        // 子进程结束
        pid_t pid = 0; 
        int stat = 0; 
        while((pid = waitpid(-1, &stat, WNOHANG)) > 0)
        {
            int index = pidIndexMap[pid];
             AppSetting::Instance()->childProcessState[index].status = 0;
            LOG_ERROR << "Child exit: " <<  AppSetting::Instance()->childProcessState[index].name << " " << pid << LOG_ENDL;
            pidIndexMap.erase(pid);
        } 
        return; 
    }
    if(signal != SIGPIPE && signal != SIGCONT)
    {
        // 记录堆栈&关闭子进程
        const int max = 50;
        void* buffer[max];
        dumpBacktrace(buffer, captureBacktrace(buffer, max));
        for(auto& child : pidIndexMap)
        {
            kill(child.first, SIGTERM);
        }
        exit(1);
    }
}

int startChild()
{
    for(int i = 0; i != 3; ++i)
    {
        if( AppSetting::Instance()->childProcessState[i].status == 0)
        {
            pid_t pid = fork();
            if(pid == 0)
            {
                auto info = AppSetting::Instance()->childProcessState[i];
                // 启动服务
                mfs::setLogfile(info.name);
                LOG_INFO << "Child start: " <<  info.name << " " << getpid() << LOG_ENDL;
                AppSetting::Instance()->typeIndex = i;
                mfs::MediaForwardService service(info.websocketPort, info.rtpPort, info.rtpPortyb,  info.infoPort, info.appPort, info.rtmpPort, info.rtpPortSend, info.rtpPortSendyb, info.name);
                service.start();
                exit(0);
            }
            else if(pid == -1)
            {
                LOG_ERROR << "error: create child process failed!" << LOG_ENDL;
                return 1;
            }
            else
            {
                pidIndexMap[pid] = i;
                 AppSetting::Instance()->childProcessState[i].status = 1;
                LOG_INFO << "Child start: " <<  AppSetting::Instance()->childProcessState[i].name << " " << pid << LOG_ENDL;
            }
        }
    }
    return 0;
}

}

std::pair<std::string, int> redisParam;

int main(int argc, char** argv)
{

    LOG_SET_CURRENT_LEVEL(mfs::LogDebug);
    // 注册信号回调
    for(int i = 1; i != 32; ++i)
    {
        if(i != SIGWINCH)
        {
            signal(i, signalCallback);
        }
    }
    
    if(argc != 2)
    {
        LOG_ERROR << "error: param error!" << LOG_ENDL;
        return 1;
    }

    AppSetting::Instance()->Load(argv[1]);
    redisParam.first = AppSetting::Instance()->redisIp;
    redisParam.second = AppSetting::Instance()->redisPort;
    // redisParam.first = argv[1];
    // redisParam.second = std::stoi(argv[2]);

#ifdef RELEASE
    // 转后台守护
     if(daemon(1, 1) == -1)
     {
         LOG_ERROR << "error: create daemon failed!" << LOG_ENDL;
         return 1;
     }
#endif

    mfs::setLogfile("main");
    LOG_INFO << "[Media Forward Service] " << __DATE__ << " " << __TIME__ << LOG_ENDL;    

#ifdef RELEASE
    // 轮询守护子进程
     while(1)
     {
         if(startChild() != 0)
         {
             return 1;
         }
         std::this_thread::sleep_for(std::chrono::milliseconds(10));
     }
#else

    int testindex = 2;
    AppSetting::Instance()->typeIndex = testindex;
    auto procedssInfo = AppSetting::Instance()->childProcessState[testindex];
    LOG_INFO << "Child start: " << procedssInfo.name << LOG_ENDL;
    mfs::MediaForwardService service(procedssInfo.websocketPort, procedssInfo.rtpPort, procedssInfo.rtpPortyb, procedssInfo.infoPort,procedssInfo.appPort,procedssInfo.rtmpPort,procedssInfo.rtpPortSend,procedssInfo.rtpPortSendyb, procedssInfo.name);
    service.start();
    exit(0);
#endif
    return 0;
}
