#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include "log_config.h"

#define _MOPEN_RILD_CONNET_NUM  5
#define _MOPEN_RILD_SOCKET "/tmp/logd_socket"

static int client_sockfd[_MOPEN_RILD_CONNET_NUM];

static const char* log_file, *log_ip, *log_port, *log_prefix, *pid_file, *hostname;
static int log_size = 1 * 1024 * 1024;

static log_config_entry* config = NULL;
static char tmp_log[48] = {0};

static int fileter_log(int pri, char* tag, struct filter_list_t* filter)
{
    struct filter_list_t* _filter = filter;

    while (_filter) {
        // _filter->priority
        // 获取 筛选的等级 p
        int p = 0;
        if (_filter->tag) {
            int len = strlen(_filter->tag);
            // tag and priority
            if (0 == memcmp(_filter->tag, tag, len) && ((pri > p) || (pri == p))) {
                return 0;
            }
        } else { // have no tag
            if (pri < p) {
                return -1;
            } else {
                return 0;
            }
        }
        _filter = _filter->next;
    }

    return -1;
}

int socket_log_print(
    int fd,
    struct file_list_t* _file_list,
    char* entry)
{
    char priChar;
    // char timeBuf[32];
    // time_t timetemp; // 定义一个时间结构体变量
    char defaultBuffer[512];
    size_t totalLen;
    int fd_new = fd;
    struct stat s;
    char* ret = NULL;

    if (log_size && (!stat(tmp_log, &s)) && (s.st_size > log_size)) {
        fd_new = get_rotate_file(fd_new, log_file, _file_list);
        if (fd_new < 0) {
            fprintf(stderr, "failed to open %s: %s\n", log_file, strerror(errno));
            exit(-1);
        }
    }

    // if(fileter_log(entry->priority, entry->tag, config->filter_list))
    // {
    // printf("%s %d: fileter pri:%d tag:%s!\n", __FUNCTION__, __LINE__, entry->priority, entry->tag);
    //     return -1;
    // }
    // time(&timetemp); // 获得时间参数
    // struct tm* ptm = localtime(&timetemp);
    // strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", ptm);
    totalLen = snprintf(defaultBuffer, sizeof(defaultBuffer), "%s", entry);

    ret = write(fd_new, defaultBuffer, totalLen);

    return ret;
}

static int open_local_socket(char *path)
{
    int listen_fd;
    int ret;
    struct sockaddr_un srv_addr;

    listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (listen_fd < 0) {
        printf("connect creat communication socket");
        return -1;
    }

    unlink(path);
    srv_addr.sun_family = AF_UNIX;
    strcpy(srv_addr.sun_path, path);

    ret = bind(listen_fd, (struct sockaddr*)&srv_addr, sizeof(srv_addr));
    if (ret < 0) {
        printf("cannot bind server socket");
        close(listen_fd);
        unlink(path);
        return -1;
    }

    return listen_fd;
}

void* socket_log_thread(void* argv)
{
    int listen_fd;
    int com_fd, fd_max, fd_num;
    int ret, log_fd;
    int i, n, str_len;
    fd_set reads, cpy_reads;
    struct timeval timeout;
    char buf[512] = {0};
    static struct file_list_t file_list;
    config = (log_config_entry*)argv;

    pthread_detach(pthread_self());
    if (NULL == argv || NULL == config->name) {
        return NULL;
    }

    memset(&file_list, 0, sizeof(struct file_list_t));
    file_list.total = config->rotate_file_count;
    log_file = config->out_path;

    if (config->ip && config->port) {
        int port = atoi(config->port);
        printf("%s %d : %s:%s\n", __FUNCTION__, __LINE__, config->ip, config->port);
        log_fd = tcp_connect(config->ip, port);
    } else if (log_file) {
        sprintf(tmp_log, "/tmp/log%s", strstr_tail(log_file, "/"));
        // 先将文件保存到 /tmp/log/ 目录下，后面到达 rotate_file_size 后，转移到out_path
        log_fd = open(tmp_log, O_CREAT | O_WRONLY | O_APPEND, 0600);
        if (log_fd < 0) {
            fprintf(stderr, "failed to open %s: %s\n", tmp_log, strerror(errno));
            exit(-1);
        }
    } else {
        log_fd = STDOUT_FILENO;
    }
    if (config->rotate_file_size) {
        log_size = config->rotate_file_size;
    }

    listen_fd = open_local_socket(_MOPEN_RILD_SOCKET);
    if (listen_fd < 0 || listen_fd == 0) {
        return NULL;
    }
    ret = listen(listen_fd, 1);
    if (ret < 0) {
        printf("cannot listen sockfd");
        close(listen_fd);
        unlink(_MOPEN_RILD_SOCKET);
        return NULL;
    }
    FD_ZERO(&reads);
    FD_SET(listen_fd, &reads);
    fd_max = listen_fd;
    printf("socket log start...\n");
    memset(client_sockfd, 0, sizeof(client_sockfd));
    for (;;) {
        cpy_reads = reads;
        timeout.tv_sec = 5;
        timeout.tv_usec = 5000;

        if ((fd_num = select(fd_max + 1, &cpy_reads, 0, 0, &timeout)) == -1) {
            perror("select error");
            break;
        }
        if (fd_num == 0) {
            continue;
        }

        for (n = 0; n < fd_max + 1; n++) {
            if (FD_ISSET(n, &cpy_reads)) {
                if (n == listen_fd) {
                    com_fd = accept(listen_fd, NULL, NULL);
                    FD_SET(com_fd, &reads);
                    if (fd_max < com_fd) {
                        fd_max = com_fd;
                    }
                    printf("accept accept fd [%d]", com_fd);
                    for (i = 0; i < _MOPEN_RILD_CONNET_NUM; i++) {
                        if (client_sockfd[i] <= 0) {
                            client_sockfd[i] = com_fd;
                            break;
                        }
                    }
                } else {
                    str_len = read(n, buf, sizeof(buf));
                    if (str_len == 0) {
                        for (i = 0; i < _MOPEN_RILD_CONNET_NUM; i++) {
                            if (client_sockfd[i] == n) {
                                client_sockfd[i] = 0;
                                break;
                            }
                        }
                        FD_CLR(n, &reads);
                        close(n);
                        printf("closed client: %d \n", n);
                    } else {
                        socket_log_print(log_fd, &file_list, buf);
                        memset(buf, 0, sizeof(buf));
                    }
                }
            }
        }
    }
    close(listen_fd);
    close(log_fd);
    unlink(_MOPEN_RILD_SOCKET);
    printf("%s exit \n", __FUNCTION__);
    pthread_exit(NULL);

    return NULL;
}
