#include "tcp_cgi.hpp"
#include "localserver/local_server.hpp"
#include <zlog.h>

extern zlog_category_t *zct;
extern zlog_category_t *zbt;

TcpCgi::TcpCgi() { zlog_info(zbt, "TcpCgi Init"); }

void TcpCgi::startCgiServer() {
    int listenfd, connfd;
    int mw_optval = 1;

    struct sockaddr_in servaddr;
    char buff[40960];
    int n;
    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        zlog_error(zbt, "create socket error: %s(errno: %d)", strerror(errno), errno);
        return;
    }
    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&mw_optval, sizeof(mw_optval));

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(7305);

    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
        zlog_error(zbt, "bind socket error: %s(errno: %d)", strerror(errno), errno);
        return;
    }

    if (listen(listenfd, 10) == -1) {
        zlog_error(zbt, "listen socket error: %s(errno: %d)", strerror(errno), errno);
        return;
    }

    while (1) {
        if ((connfd = accept(listenfd, (struct sockaddr *)NULL, NULL)) == -1) {
            zlog_error(zct, "accept socket error: %s(errno: %d)", strerror(errno), errno);
            continue;
        }
        n = recv(connfd, buff, 40960, 0);
        if (n <= 0) {
            zlog_info(zct, "recv 0 and will close");
            close(connfd);
        } else {
            buff[n] = '\0';

            std::string recvData = std::string(buff);
            std::string reqData = LocalServer::HandleCgi_cmd(recvData);
            if (send(connfd, reqData.c_str(), reqData.length(), 0) < 0) {
                zlog_error(zct, "send msg error: %s(errno: %d)", strerror(errno), errno);
            }
            close(connfd);
        }
    }
    close(listenfd);
    return;
}

TcpCgi::~TcpCgi() {}
