#include <errno.h>
#include <signal.h>
#include <semaphore.h>

#include "log_common.h"
#include "ulog_api.h"

#include <unistd.h>

#define SEV_TIMEOUT             1
#define SEV_CMD                 "systemctl restart rsyslog"

typedef enum {
   SEV_STATE_RESTARTING,
   SEV_STATE_WAIT
} sev_state_t;

static sem_t g_sem;
static volatile int g_is_exit = 0;
static volatile sev_state_t g_sev_state = SEV_STATE_WAIT;

void sev_restart()
{
	ULOG_DEBUG(g_log, "Log service is restarting");

    FILE *pp = popen(SEV_CMD, "r");
    if (pp == NULL) {
        ULOG_ERR(g_log, "Open cmd:%s is failure:%s", SEV_CMD, strerror(errno));
        goto END;
    }

    char buff[256];
    while(fread(buff, 1, sizeof(buff), pp) > 0)
	{
		ULOG_ERR(g_log, "Executing cmd:%s is failure, response content is %s", SEV_CMD, buff);
        goto END;
	}
    ULOG_INFO(g_log, "Restarting log service is success");

END:
    if (pp != NULL) {
        pclose(pp);
    }
	//event_del(signal);
}

void sev_loop()
{
    while (1) {
        if (sem_wait(&g_sem) != 0) {
            ULOG_ERR(g_log, "Waitting semaphore is failure:%s", strerror(errno));
            break;
        }
        g_sev_state = SEV_STATE_RESTARTING;
        if (g_is_exit == 1) {
            ULOG_DEBUG(g_log, "Service loop is exit");
            break;
        }
        
        // 减少在短时间内频繁更改配置使重启变多,这里进行限制
        sleep(SEV_TIMEOUT);
        g_sev_state = SEV_STATE_WAIT;
        sev_restart();
    }
}

int log_sev_init()
{   
    ULOG_INFO(g_log, "Log service is initiating");
    if (sem_init(&g_sem, 0, 0) != 0) {
        ULOG_ERR(g_log, "Init sem is failure:%s", strerror(errno));
        return -1;
    }

    return 0;
}

static int set_sem()
{
    if (sem_post(&g_sem) == -1) {        
        ULOG_ERR(g_log, "Posting semaphore is failure:%s", strerror(errno));
        return -1;
    }
    return 0;
}

int log_sev_exit()
{
    g_is_exit = 1;
    set_sem();
    sem_destroy(&g_sem);

    return 0;
}

int log_sev_restart()
{
    /*
    int val;
    if (sem_getvalue(&g_sem, &val) != 0) {
        ULOG_ERR(g_log, "Get semaphore value is failure:%s", strerror(errno));
        return -1;
    }

    if (val > 0) {
        ULOG_ERR(g_log, "Current semaphore value is %d, not need to set semaphore");
        return 0;
    } 
    */
    if (g_sev_state == SEV_STATE_RESTARTING) {
        ULOG_DEBUG(g_log, "Current service state:%u, not need to set semaphore", g_sev_state);
        return 0;
    }

    if (set_sem() != 0) {
        return -1;
    }

    return 0;
}