#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

#include "entrance_guard_common.h"

static int entrance_guard_mqtt_handle_recv_msg(void *obj, ipc_msg_t *mqtt_msg)
{
    entrance_guard_var_t *var = (entrance_guard_var_t *)obj;
    dy_syslog(LOG_DEBUG, "received MQTT topic:%s payload length:%d", mqtt_msg->topic, mqtt_msg->payloadLen);
    if (strstr(mqtt_msg->topic, TOPIC_SEND_RGLT_SIGNAL_RAW_DATA))
    {
        //发送下行数据
        // entrance_guard_msg_tag_data_ctrl(var, mqtt_msg);
    }

    return 0;
}

static void entrance_guard_subscribe_all(entrance_guard_var_t *var)
{
    ipc_session_t *ipc_session = var->session;
    char topic[TOPIC_MAX_LEN] = {0};

    snprintf(topic, TOPIC_MAX_LEN, "ipc/+/%s/device/+/data/%s", ENTRANCE_GUARD_APP_KEY, TOPIC_SEND_RGLT_SIGNAL_RAW_DATA);
    ipc_session_subscribe(ipc_session, topic);
    snprintf(topic, TOPIC_MAX_LEN, "ipc/+/%s/%s", ENTRANCE_GUARD_APP_KEY, TOPIC_NOTIFY_UPGRADE);
    ipc_session_subscribe(ipc_session, topic);
}

// 建立与内部broker之间的MQTT连接
static int entrance_guard_mqtt_client_init(entrance_guard_var_t *var)
{
    char clientId[MAX_CLIENT_ID_LEN] = {0};

    snprintf(clientId, MAX_CLIENT_ID_LEN, "INT_entrance_guard_%s", var->sn_str);
    var->session = ipc_session_new(clientId, (void*)var, IPC_DEFAULT);
    if (var->session == NULL)
        return -1;

    ipc_session_set_callbacks(var->session, entrance_guard_mqtt_handle_recv_msg, NULL);
    entrance_guard_subscribe_all(var);
    ipc_session_start(var->session);


    return 0;
}

static int entrance_guard_init(entrance_guard_var_t *var)
{
    int count;

    get_board_sn(var->sn_str);
    get_process_name(var->proc_name);

    if (load_nodes_cfg(&var->nodes_cfg_table, NODES_CFG_PATH) == -1)
    {
        dy_syslog(LOG_ERR, "load nodes cfg fail");
    }
    if (load_templates_cfg(&var->template_table, TEMPLATES_CFG_PATH) == -1)
    {
        dy_syslog(LOG_ERR, "load template cfg fail");
    }
    if (load_objects_cfg(&var->object_table, OBJECTS_CFG_PATH) == -1)
    {
        dy_syslog(LOG_ERR, "load object cfg fail");
    }

    pthread_mutex_init(&var->open_door_lock, NULL);
    lnxall_condvar_init(&var->open_door_cond);
    INIT_LIST_HEAD(&var->open_door_list);
    count = get_new_entrance_guard_data_count(var);
    if (count < 0)
    {
        dy_syslog(LOG_ERR, "get original entrance guard data count fail");
    }
    else
    {
        var->last_id = count;
    }
    entrance_guard_mqtt_client_init(var);

    var->inquire_timer = my_timer_create();
    if (var->inquire_timer > 0)
    {
        my_timer_set(var->inquire_timer, 1, 2000);
    }

    var->poll_timer = my_timer_create();
    if (var->poll_timer > 0)
    {
        my_timer_set(var->poll_timer, 1, 5000);
    }
    entrance_guard_start_thread(var);

    return 0;
}

static int entrance_guard_poll(entrance_guard_var_t *var)
{
    TIMER_CONFIRM(var->poll_timer);

    return 0;
}

static void entrance_guard_loop(entrance_guard_var_t *var)
{
    int ret = -1, maxfd;
    fd_set rset;
    struct timeval timeout;

    while (1)
    {
        SELECT_INIT();
        SELECT_ADD_FD(var->poll_timer);
        timeout.tv_usec = 0;
        timeout.tv_sec = 10;
        ret = select(maxfd + 1, &rset, 0, 0, &timeout);
        if (ret < 0)
        {
            printf("errno %d\n", errno);
            if (errno == EINTR)
            {
                continue;
            }
            else
            {
                break;
            }
        }
        else if (ret == 0)
        {
        }
        else
        {
            if (var->poll_timer > 0 && FD_ISSET(var->poll_timer, &rset))
            {
                FD_CLR(var->poll_timer, &rset);
                entrance_guard_poll(var);
            }
        }
    }
}

int main(int argc, char *argv[])
{
    entrance_guard_var_t var = {0};

    memset(&var, 0, sizeof(entrance_guard_var_t));
    openlog("entrance_guard", LOG_PID, LOG_DAEMON);

    entrance_guard_init(&var);
    entrance_guard_loop(&var);

    return 0;
}
