classDiagram
    direction TB

    class Server {
        +Server(const ConfigManager&)
        +~Server()
        +start()
        +addToEpoll(Socket&, uint32_t)
        +removeFromEpoll(Socket&)
        +setupServerSocket(ServerConfig&)
        +handleConnection(epoll_event*)
        +handleRequest(epoll_event*)
        +responseReady(int)
        +eventLoop()
        +getListener(int) Socket&
        +getClient(int) Client&
        +getConfig(int) ServerConfig&
        +getConfig(Socket&) ServerConfig&
        -int epoll_fd_
        -ConfigManager& configManager_
        -vector<unique_ptr<Socket>> listeners_
        -unordered_map<int, ServerConfig&> fdToConfig_
        -unordered_map<int, unique_ptr<Client>> clients_
    }

    class Socket {
        +Socket()
        +Socket(int)
        +~Socket()
        +listen(int) void
        +bind(string, int) void
        +accept() Socket*
        +recv(void*, size_t) ssize_t
        +send(const void*, size_t) ssize_t
        +setNonBlocking() void
        +getFd() int
        -int _fd
    }

    class Client {
        +Client(unique_ptr<Socket>, Server&, ServerConfig&)
        +~Client()std::move(clientSocket), *this, getConfig(listener)
        +request() void
        +getResponse() string
        -unique_ptr<Socket> client_socket_
        -Server& server
        -ServerConfig& server_config
    }

    class ConfigManager {
        +init(string)
        +getInstance() ConfigManager&
        +getServerConfigs() vector<ServerConfig>
        -bool _initialized
        -vector<ServerConfig> serverConfigs
    }

    class ServerConfig {
        +ServerConfig(string)
        +getHost() string
        +getPort() int
        +getRoot() string
        +getCgiPass() string
        +getCgiExt() string
        +getErrorPages() map<int,string>
        +getIndexFiles() vector<string>
        +getLocation(string) LocationConfig&
        +getLocationPaths() vector<string>
        +setServerFD(int)
        +getServerFD() int
        -string host
        -int port
        -int server_fd
        -string root
        -string cgi_pass
        -string cgi_ext
        -map<int,string> error_page
        -vector<string> index_files
        -map<string, LocationConfig> locations
    }

    class LocationConfig {
        +LocationConfig(string)
        -string path
        -bool autoIndex
        -string indexFile
        -map<string,string> directives
    }

    class HttpRequest {
        +HttpRequest()
        +parse(string) bool
        +getMethod() string
        +getPath() string
        +getVersion() string
        +getHeader(string) string
        +getHeaders() map<string,string>
        +getBody() string
        +hasHeader(string) bool
        +isComplete() bool
        -string method
        -string path
        -string version
        -map<string,string> headers
        -string body
        -bool complete
    }

    class HttpResponse {
        +HttpResponse()
        +setStatus(int)
        +setHeader(string, string)
        +setBody(string)
        +toString() string
        +sendFile(string)
        +sendError(int)
        -int status_code
        -string status_message
        -map<string,string> headers
        -string body
    }

    class Router {
        +Router(ServerConfig&)
        +route(HttpRequest&) HttpResponse
        +handleGet(HttpRequest&) HttpResponse
        +handlePost(HttpRequest&) HttpResponse
        +handleDelete(HttpRequest&) HttpResponse
        +serveFile(string) HttpResponse
        +listDirectory(string) HttpResponse
        +matchLocation(string) LocationConfig&
        -ServerConfig& config
    }

    class CgiHandler {
        +CgiHandler(LocationConfig&)
        +execute(HttpRequest&) HttpResponse
        +setupEnvironment(HttpRequest&)
        +executeScript(string, HttpRequest&) string
        +setTimeout(int)
        -LocationConfig& location
        -map<string,string> env_vars
        -int timeout
    }

    class ConfigValidator {
        +validate(ConfigManager&) bool
        +validateServerConfig(ServerConfig&) bool
        +validateLocationConfig(LocationConfig&) bool
        +checkPortConflicts() bool
        +checkPathExists(string) bool
        +validateDirective(string, string) bool
        -vector<string> errors
        -vector<string> warnings
    }

    class Logger {
        +info(string)
        +warn(string)
        +error(string)
        +debug(string)
        +setLevel(LogLevel)
        -LogLevel level
        -ofstream logFile
    }

    class MimeTypeHandler {
        +getMimeType(string) string
        +loadMimeTypes()
        -map<string,string> mimeTypes
    }

    Server "1" o-- "1..*" Socket : listens on
    Server "1" o-- "0..*" Client : manages
    Server "1" -- "1" ConfigManager : uses
    Client "1" *-- "1" Socket : owns
    Client "1" -- "1" Server : references
    Client "1" -- "1" ServerConfig : references
    Client "1" -- "1" HttpRequest : processes
    Client "1" -- "1" HttpResponse : generates
    ServerConfig "1" o-- "*" LocationConfig : has
    Router "1" -- "1" ServerConfig : uses
    Router "1" -- "*" CgiHandler : may use
    CgiHandler "1" -- "1" LocationConfig : uses
    ConfigManager "1" -- "1" ConfigValidator : validates with
    Router "1" -- "1" MimeTypeHandler : uses
    Server "1" -- "1" Logger : logs to