/*
*    gnss_ipc.c
*
*    MBTK GNSS IPC service source.
*
*/
/******************************************************************************

                          EDIT HISTORY FOR FILE

  WHEN        WHO       WHAT,WHERE,WHY
--------    --------    -------------------------------------------------------
2024/6/15     LiuBin      Initial version

******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <pthread.h>
#include <sys/epoll.h>

#include "mbtk_log.h"
#include "mbtk_type.h"
#include "gnss_info.h"

#define GNSS_SOCK_PATH "/tmp/mbtk_gnss_sock"
#define SOCK_CLIENT_MAX 3
#define EPOLL_LISTEN_MAX 100

static int sock_listen_fd = -1;
static int sock_cli_fds[SOCK_CLIENT_MAX];

int gnss_write(int fd, const void* buf, unsigned int buf_len);
int gnss_agnss_get_eph(const void* param);


static int gnss_cli_fd_find(int fd)
{
    int i = 0;
    while(i < SOCK_CLIENT_MAX) {
        if(fd == sock_cli_fds[i])
            return i;
        i++;
    }

    return -1;
}

static void gnss_msg_process(int fd, const char *msg, int msg_len)
{
    LOGD("CMD <%s>", msg);
    // gnss_init:x
    usleep(10 * 1000); // sleep 10ms
    if(memcmp(msg, "gnss_init", 9) == 0) {
        int init_mode = atoi(msg + 10);
        int ret = 0;
        if(init_mode == 0) { // Close gnss.
            ret = gnss_deinit();
        } else {
            // ARG error, no print nmea.
            if(((GNSS_PRINT_PORT_UART1 | GNSS_PRINT_PORT_USB_NMEA | GNSS_PRINT_PORT_USB_AT | GNSS_PRINT_PORT_TTY_AT) & init_mode) != init_mode) {
                init_mode = 0;
            }
            ret = gnss_init(init_mode);
        }

        char rsp[100] = {0};
        sprintf(rsp, "%cgnss_init:%d%c", MBTK_IND_START_FLAG, ret, MBTK_IND_END_FLAG);
        gnss_write(fd, rsp, strlen(rsp));
    } else if(memcmp(msg, "gnss_deinit", 11) == 0) { // gnss_deinit
        int ret = gnss_deinit();

        char rsp[100] = {0};
        sprintf(rsp, "%cgnss_deinit:%d%c", MBTK_IND_START_FLAG, ret, MBTK_IND_END_FLAG);
        gnss_write(fd, rsp, strlen(rsp));
    } else if(memcmp(msg, "gnss_setting", 12) == 0) {// gnss_setting:cmd
        char cmd_rsp[513] = {0};
        int ret = gnss_set(msg + 13, strlen(msg + 13), cmd_rsp, 512);

        char rsp[1024] = {0};
        sprintf(rsp, "%cgnss_setting:%d %s%c", MBTK_IND_START_FLAG, ret, strlen(cmd_rsp) > 0 ? cmd_rsp : "NULL", MBTK_IND_END_FLAG);
        gnss_write(fd, rsp, strlen(rsp));
    } else if(memcmp(msg, "gnss_dl", 7) == 0) {// gnss_dl:fw_name
        int ret = gnss_dl_fw(msg + 8, NULL, 0);

        char rsp[100] = {0};
        sprintf(rsp, "%cgnss_dl:%d%c", MBTK_IND_START_FLAG, ret, MBTK_IND_END_FLAG);
        gnss_write(fd, rsp, strlen(rsp));
    } else if(memcmp(msg, "gnss_agnss_get", 14) == 0) {// gnss_agps_get
        int ret = gnss_agnss_get_eph(msg + 15);

        char rsp[100] = {0};
        sprintf(rsp, "%cgnss_agnss_get:%d%c", MBTK_IND_START_FLAG, ret, MBTK_IND_END_FLAG);
        gnss_write(fd, rsp, strlen(rsp));
    } else if(memcmp(msg, "gnss_agnss_set", 14) == 0) {// gnss_agps_set
        int ret = gnss_agnss_inject();

        char rsp[100] = {0};
        sprintf(rsp, "%cgnss_agnss_set:%d%c", MBTK_IND_START_FLAG, ret, MBTK_IND_END_FLAG);
        gnss_write(fd, rsp, strlen(rsp));
    } else if(memcmp(msg, "gnss_ind", 8) == 0) {// gnss_ind:ind_type
        int ind_type = atoi(msg + 9);
        int ret = gnss_ind_set(fd, ind_type);

        char rsp[100] = {0};
        sprintf(rsp, "%cgnss_ind:%d%c", MBTK_IND_START_FLAG, ret, MBTK_IND_END_FLAG);
        gnss_write(fd, rsp, strlen(rsp));
    } else {
        LOGW("Unknown gnss msg : %s", msg);
    }
}

static void* gnss_ser_pthread(void* arg)
{
    UNUSED(arg);
    int epoll_fd = epoll_create(SOCK_CLIENT_MAX + 1);
    if(epoll_fd < 0)
    {
        LOGE("epoll_create() fail[%d].", errno);
        return NULL;
    }

    int i = 0;
    while(i < SOCK_CLIENT_MAX) {
        sock_cli_fds[i++] = -1;
    }

    uint32 event = EPOLLIN | EPOLLET;
    struct epoll_event ev;
    ev.data.fd = sock_listen_fd;
    ev.events = event; //EPOLLIN | EPOLLERR | EPOLLET;
    epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sock_listen_fd, &ev);

    int nready = -1;
    struct epoll_event epoll_events[EPOLL_LISTEN_MAX];
    while(1)
    {
        nready = epoll_wait(epoll_fd, epoll_events, EPOLL_LISTEN_MAX, -1);
        if(nready > 0)
        {
            for(i = 0; i < nready; i++)
            {
                LOGD("fd[%d] event = %x",epoll_events[i].data.fd, epoll_events[i].events);
                if(epoll_events[i].events & EPOLLHUP)   // Client Close.
                {
                    int index = gnss_cli_fd_find(epoll_events[i].data.fd);
                    if(index != -1)
                    {
                        memset(&ev,0,sizeof(struct epoll_event));
                        ev.data.fd = epoll_events[i].data.fd;
                        ev.events = EPOLLIN | EPOLLERR | EPOLLET;
                        epoll_ctl(epoll_fd, EPOLL_CTL_DEL, epoll_events[i].data.fd, &ev);

                        close(epoll_events[i].data.fd);
                        sock_cli_fds[index] = -1;

                        // Clear IND flag.
                        gnss_ind_set(epoll_events[i].data.fd, 0);
                    }
                    else
                    {
                        LOGE("Unknown client[fd = %d].", epoll_events[i].data.fd);
                    }
                }
                else if(epoll_events[i].events & EPOLLIN)
                {
                    if(epoll_events[i].data.fd == sock_listen_fd)   // New clients connected.
                    {
                        int client_fd = -1;
                        while(1)
                        {
                            struct sockaddr_in cliaddr;
                            socklen_t clilen = sizeof(cliaddr);
                            client_fd = accept(epoll_events[i].data.fd, (struct sockaddr *) &cliaddr, &clilen);
                            if(client_fd <= 0)
                            {
                                if(errno == EAGAIN)
                                {
                                    LOGE("All client connect get.");
                                }
                                else
                                {
                                    LOGE("accept() error[%d].", errno);
                                }
                                break;
                            } else {
                                i = 0;
                                while(i < SOCK_CLIENT_MAX) {
                                    if(sock_cli_fds[i] <= 0) {
                                        sock_cli_fds[i] = client_fd;
                                        break;
                                    }
                                    i++;
                                }

                                if(i >= SOCK_CLIENT_MAX) {
                                    LOGE("Client is full.");
                                    break;
                                }
                            }
                            // Set O_NONBLOCK
                            int flags = fcntl(client_fd, F_GETFL, 0);
                            if (flags > 0)
                            {
                                flags |= O_NONBLOCK;
                                if (fcntl(client_fd, F_SETFL, flags) < 0)
                                {
                                    LOGE("Set flags error:%d", errno);
                                }
                            }

                            memset(&ev,0,sizeof(struct epoll_event));
                            ev.data.fd = client_fd;
                            ev.events = event;//EPOLLIN | EPOLLERR | EPOLLET;
                            epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev);
                        }
                    }
                    else if(epoll_events[i].data.fd > 0)    // Client data arrive.
                    {
                        char buff[1024] = {0};
                        int len = read(epoll_events[i].data.fd, buff, sizeof(buff));
                        if(len > 0) {
                            gnss_msg_process(epoll_events[i].data.fd, buff, len);
                        }
                    }
                    else
                    {
                        LOGE("Unknown socket : %d", epoll_events[i].data.fd);
                    }
                }
                else
                {
                    LOGE("Unknown event : %x", epoll_events[i].events);
                }
            }
        }
        else
        {
            LOGE("epoll_wait() fail[%d].", errno);
        }
    }

    return NULL;
}


int gnss_ipc_service_start()
{
    struct sockaddr_un server_addr;
    sock_listen_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
    if(sock_listen_fd < 0)
    {
        LOGE("socket() fail[%d].", errno);
        return -1;
    }

    // Set O_NONBLOCK
    int flags = fcntl(sock_listen_fd, F_GETFL, 0);
    if (flags < 0)
    {
        LOGE("Get flags error:%d", errno);
        goto error;
    }
    flags |= O_NONBLOCK;
    if (fcntl(sock_listen_fd, F_SETFL, flags) < 0)
    {
        LOGE("Set flags error:%d", errno);
        goto error;
    }

    unlink(GNSS_SOCK_PATH);
    memset(&server_addr, 0, sizeof(struct sockaddr_un));
    server_addr.sun_family = AF_LOCAL;
    strcpy(server_addr.sun_path, GNSS_SOCK_PATH);
    if(bind(sock_listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)))
    {
        LOGE("bind() fail[%d].", errno);
        goto error;
    }

    if(listen(sock_listen_fd, SOCK_CLIENT_MAX))
    {
        LOGE("listen() fail[%d].", errno);
        goto error;
    }

    pthread_t pid;
    pthread_attr_t thread_attr;
    pthread_attr_init(&thread_attr);
    if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
    {
        LOGE("pthread_attr_setdetachstate() fail.");
        goto error;
    }

    if(pthread_create(&pid, &thread_attr, gnss_ser_pthread, NULL))
    {
        LOGE("pthread_create() fail.");
        goto error;
    }

    LOGD("GNSS IPC service is running...");
    return 0;
error:
    close(sock_listen_fd);
    return -1;
}

