/** 
 * @brief pool select
 * @return void
 */
void SelPool::Select()
{
    printf("Selecting in server and %d clients...\n", clients.size());

    FD_ZERO(&read_set);
    FD_ZERO(&write_set);
    FD_SET(listenfd, &read_set);
    vector<ClientConnection*>::iterator it = clients.begin();
    while ( it != clients.end() )
    {
        ClientConnection *client = *it;
        int connFd = client->getFd();

        if( client->isEmpty() && client->isReadable())
        {
            printf("put %d to read_set\n", connFd);
            FD_SET(connFd, &read_set);
        }
        if( client->isWritable() ) /* state == Writing_Response */
        {
            printf("put %d to write_set\n", connFd);
            FD_SET(connFd, &write_set);
            /* if it is CGI request, put its CGI_out pipe to read set */
            if (client->getRequest()->isCGIRequest()) {
                int CGIout = client->getResponse()->getCGIout();
                if (CGIout > maxfd) {
                    maxfd = CGIout;
                }
                FD_SET(CGIout, &read_set);
            }
        }
        it++;
    }

    nready = select(maxfd + 1, &read_set, &write_set, NULL, NULL);
    //printf("Select Finished\n");
}
/** @brief check select pool and process client reqeusts
 *
 *  @param pool select pool
 *  @return void
 */
void SelPool::check_clients() 
{
    int connfd;

    vector<ClientConnection*>::iterator it = clients.begin();
    while ( it != clients.end() )
    {
        ClientConnection *client = *it;
        connfd = client->getFd();
        printf("Handling %d\n", connfd);

        /* Client Connection State Machine */
        switch ( client->getState() )
        {
            case ClientConnection::Ready_ForRead:
            {
                printf("Client State: Ready_ForRead\n");
                /* read ready client socket */
                if (FD_ISSET(connfd, &read_set))
                {
                    readHandler(client);
                    if (client->getState() == ClientConnection::Request_Parsed)
                    {
                        processHandler(client);
                        /* if the client is closed after processing */
                        if (client->getState() == ClientConnection::Closed)
                        {
                            Socket::Close_Socket(connfd);
                            FD_CLR(connfd, &read_set);
                            delete client;
                            clients.erase(it);
                            continue;
                        }
                        writeHandler(client);
                    }
                }
                break;
            }

            case ClientConnection::Request_Parsed: {
                printf("Client State: Request_Parsed\n");
                break;
            }

            case ClientConnection::Writing_Response: 
            {
                printf("Client State: Writing_Response\n");
                if (FD_ISSET(connfd, &write_set)) 
                {
                    if (!client->getRequest()->isCGIRequest())
                    {
                        processHandler(client);
                        writeHandler(client);
                    }
                    else if (FD_ISSET(client->getResponse()->getCGIout(), &read_set))
                    {
                        /* CGI request : if CGIout is also ready for reading */
                        pipeHandler(client);
                        writeHandler(client);
                    }
                }
                break;
            }

            case ClientConnection::Done_Response: {
                printf("Client State: Done_Response\n");
                break;
            }

            default: {
                break;
            }
        }
        it++;
    }
}