HDTBReturnItem NetworkClient::send(std::string message)
{
    if (!statusInfo.connectionSet)
        return HDTBReturnItem(HDTB_RETURN_BAD, "Connection not setup. [setInfo]");

    if (!send_data(message))
        return errorHandler.generateGenericError("Unable to send data.");
    return HDTBReturnItem(HDTB_RETURN_GOOD, "");
}
      HDTBReturnItem SoftwareSubModuleModify::modifyJava()
      {
        #ifdef _WIN32

            system("start lib\\software\\fixJava.bat");
            return HDTBReturnItem(HDTB_RETURN_GOOD, "");

        #elif __APPLE__
            system("lib/software/fixJavaMac.sh");
            return HDTBReturnItem(HDTB_RETURN_GOOD, "");
        #else
            return errorHandler.generateGenericError("OS not supported");
        #endif
      }
    HDTBReturnItem SoftwareSubModuleInstall::installJava()
    {
        #ifdef _WIN32

            std::string exec = ("start powershell.exe -ExecutionPolicy Bypass -File lib\\software\\installJava.ps1 \n" );
            system(exec.c_str());

            system("start lib\\software\\fixJava.bat");
            return HDTBReturnItem(HDTB_RETURN_GOOD, "");
        #elif __APPLE__
            system("lib/software/installJavaMac.sh");
            return HDTBReturnItem(HDTB_RETURN_GOOD, "");
        #else
            return errorHandler.generateGenericError("OS not supported");
        #endif
    }
 HDTBReturnItem SoftwareSubModuleInstall::installAvira()
 {
     #ifdef _WIN32
         return HDTBReturnItem(HDTB_RETURN_BAD, "Not yet programmed");
     #elif __APPLE__
         return errorHandler.generateGenericError("OS not yet supported");
     #else
         return errorHandler.generateGenericError("OS not supported");
     #endif
 }
HDTBReturnItem NetworkClient::initiateBlindComms()
{
    if (!statusInfo.connectionSet)
        return HDTBReturnItem(HDTB_RETURN_BAD, "Connection not setup. [setInfo]");

#ifdef _WIN32
    return errorHandler.generateGenericError("Not yet created for this platform");
#else
    return errorHandler.generateGenericError("Not yet created for this platform");
#endif
}
HDTBReturnItem NetworkModule::reset()
{
#ifdef __APPLE__
    system("sudo ifconfig en0 down");
    system("sudo ifconfig en0 up");

#elif _WIN32
    system("ipconfig /release");
    system("ipconfig /renew");
#endif
    return HDTBReturnItem(HDTB_RETURN_GOOD, "");
}
HDTBReturnItem NetworkModule::ping(std::string ip, std::string count)
{
    std::cout << "Ping : " << ip << " " << count << " time(s)" << std::endl;

#ifdef __APPLE__
    system(("ping -c " + count + " " + ip).c_str());

#elif _WIN32
    system(("ping -n " + count + " " + ip).c_str());
#endif
    return HDTBReturnItem(HDTB_RETURN_GOOD, "");
}
HDTBReturnItem NetworkModule::setupConnection(std::string address, std::string port)
{
    std::vector<std::string> request;
    request.push_back("setInfo");
    request.push_back(address);
    request.push_back(port);

    // Process command
    HDTBReturnItem ri =  netClient.processRequest(request);

    switch(ri.retCode)
    {
    case HDTB_RETURN_GOOD:
        // Double check to make sure connection was set
        if(!netClient.getConnectionSetState())
            return HDTBReturnItem(HDTB_RETURN_BAD,
                                  "Good report, but connection not set");
        // Return good
        return HDTBReturnItem(HDTB_RETURN_GOOD, "");
        break;

    case HDTB_RETURN_BAD:
    {
        // Relay error
        return HDTBReturnItem(HDTB_RETURN_BAD, ri.message);
    }
        break;

    case HDTB_RETURN_EXIT:
        return HDTBReturnItem(HDTB_RETURN_EXIT, "");
        break;

    default:
        errorHandler.generateGenericError("Default reached in human interaction");
        break;
    }
    return errorHandler.generateGenericError("Uncaught return");
}
HDTBReturnItem NetworkClient::kill()
{
    if(statusInfo.connectionSet)
        close_current();

    if(statusInfo.comm)
        statusInfo.comm = false;

    if(statusInfo.blindComm)
        statusInfo.blindComm = false;

    statusInfo.connectionSet = false;
    return HDTBReturnItem(HDTB_RETURN_GOOD, "");
}
HDTBReturnItem NetworkClient::processRequest(std::vector<std::string> args)
{
/*
    std::cout << "ARGUMENTS IN" << std::endl;
    for(std::vector<std::string>::iterator it = args.begin();
        it != args.end(); ++it)
    {
        std::cout << "ARG :" << *it << std::endl;
    }
*/

    history.push(args);

    // Make sure command exists
    if(commands.find(args[0]) == commands.end())
    {
        // Call to super class
        displayAvailableCommands();

        for(std::vector<std::string>::iterator it = args.begin();
            it != args.end(); ++it)
        {
            std::cout << "ARG :" << *it << std::endl;
        }

        return errorHandler.generateGenericError("Unknown command");
    }

    //Handle command
    int c = 0;
    switch(commands[args[0]])
    {

    case HDTB_CLIENT_LOAD:
        if (args.size() != 3)
        {
            std::cout << " CLIENT_LOAD " << std::endl;
            return HDTBReturnItem(HDTB_RETURN_BAD, "not enough args -setinfo <<");
        }

        // Make sure port is int
        if( !( c = atoi(args[2].c_str())) )
            return HDTBReturnItem(HDTB_RETURN_BAD, "invalid port");

        return setConnectionInfo(args[1], c);
        break;

    case HDTB_CLIENT_SEND:
    {
        if (args.size() != 2)
            return HDTBReturnItem(HDTB_RETURN_BAD, "not enough args -fsend");

        HDTBReturnItem t = send(args[2]);
        if(t.retCode == HDTB_RETURN_GOOD)
        {
            if(recieve_data())
            {
                std::cout << "\t Recieved data back from " << connectionInfo.address << std::endl;
                t.message = statusInfo.data_received;
                t.comm = 'R';
            }
            else
            {
                std::cout << "\t Didn't recieve any data back from " << connectionInfo.address << std::endl;
                t.comm = 'N';
            }
            return t;
        }
        else
            return t;

        return send(args[2]);
        break;
    }

    case HDTB_CLIENT_COMM:
        return initiateComms();
        break;

    case HDTB_CLIENT_BLIND_COMM:
        return initiateBlindComms();
        break;

    case HDTB_NETWORK_CMD_KILL:
        return kill();
        break;

    default:
        return errorHandler.generateGenericError("Default accessed in command switch");
        break;
    }
    return errorHandler.generateGenericError("Uncaught return");
}
HDTBReturnItem NetworkClient::setConnectionInfo(std::string address, int port)
{
    if(statusInfo.comm)
        return HDTBReturnItem(HDTB_RETURN_BAD,
                              "Can not process request. Comm currently open");

    if(statusInfo.blindComm)
        return HDTBReturnItem(HDTB_RETURN_BAD,
                              "Can not process request. Blind comm currently open");

#ifdef _WIN32
    return errorHandler.generateGenericError("OS not yet supported");
#else

    // If its already connected, close it.
    if(statusInfo.connectionSet)
        close_current();

    // Set the connection information
    connectionInfo.port = port;
    connectionInfo.address = address;
    connectionInfo.sock = -1;

    //Create socket
    connectionInfo.sock = socket(AF_INET , SOCK_STREAM , 0);
    if (connectionInfo.sock == -1)
        return errorHandler.generateGenericError("Unable to create socket");

    // Make sure address is ip
    // Ignore the warning generated
    if(inet_addr(connectionInfo.address.c_str()) == -1)
    {
        struct hostent * record = gethostbyname(connectionInfo.address.c_str());
        if(record == NULL)
            return errorHandler.generateGenericError("Unable to resolve hostname");

        in_addr * addy = (in_addr * )record->h_addr;
        connectionInfo.address = inet_ntoa(*addy);

        std::cout << "Address resolved to : " << connectionInfo.address << std::endl;
    }

    // If we already have an ip, set the connection
    connectionInfo.addr_in.sin_addr.s_addr = inet_addr( connectionInfo.address.c_str() );
    connectionInfo.addr_in.sin_family = AF_INET;
    connectionInfo.addr_in.sin_port = htons( connectionInfo.port );

    std::cout << "\t Attempting to make connection. This might take a moment " << std::endl;

    // Make the connection
    if (connect(connectionInfo.sock ,
                (struct sockaddr *)&connectionInfo.addr_in ,
                 sizeof(connectionInfo.addr_in)) < 0)
    {
        return errorHandler.generateGenericError("Unable to connect to address");
    }
    else
    {
        // Indicate what was done
        statusInfo.connectionSet = true;
        return HDTBReturnItem(HDTB_RETURN_GOOD, "");
    }
#endif
}