#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <thread>
#include <string>
#include <cstring>
#include <iostream>

void handleEvent(const std::string& json) {
    // parse and handle the event
    // for now just print it
    std::cout << "Event: " << json << std::endl;
}

void runSocketServer() {
    int serverFd = socket(AF_UNIX, SOCK_STREAM, 0);

    struct sockaddr_un addr;
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, "/tmp/cheatnt.sock", sizeof(addr.sun_path) - 1);

    unlink("/tmp/cheatnt.sock");
    bind(serverFd, (struct sockaddr*)&addr, sizeof(addr));
    listen(serverFd, 1);

    std::cout << "Waiting for VS Code extension..." << std::endl;

    while (true) {
        int clientFd = accept(serverFd, nullptr, nullptr);
        if (clientFd < 0) continue;

        std::cout << "Extension connected" << std::endl;

        // handle client in a thread
        std::thread([clientFd]() {
            char buf[4096];
            std::string partial;

            while (true) {
                ssize_t n = read(clientFd, buf, sizeof(buf));
                if (n <= 0) break;

                partial += std::string(buf, n);

                // events are newline delimited
                size_t pos;
                while ((pos = partial.find('\n')) != std::string::npos) {
                    std::string line = partial.substr(0, pos);
                    partial = partial.substr(pos + 1);
                    if (!line.empty()) {
                        handleEvent(line);
                    }
                }
            }

            close(clientFd);
            std::cout << "Extension disconnected" << std::endl;
        }).detach();
    }
}

int main() {
    runSocketServer();
    return 0;
}
