int main(int argc, char*argv[]) {

	pthread_mutex_init(&semModificadorDeVidas, NULL);
	sem_init(&semReinicio, 0, 0);
	sem_init(&semFinPlan, 0, 0);

	// Inicializa el log.
	logger = logInit(argv, "PERSONAJE");

	if (signal(SIGINT, muertoPorSenial) == SIG_ERR) {
		log_error(logger, "Error en el manejo de la senal de muerte del personaje.\n", stderr);
		exit(EXIT_FAILURE);
	}

	if (signal(SIGTERM, restarVida) == SIG_ERR) {
		log_error(logger, "Error en el manejo de la senal de restar vidas del personaje.\n", stderr);
		exit(EXIT_FAILURE);
	}

	if (signal(SIGUSR1, sig_aumentar_vidas) == SIG_ERR) {
		log_error(logger, "Error en el manejo de la senal de de aumentar vidas del personaje.\n", stderr);
		exit(EXIT_FAILURE);
	}

	// Creamos el archivo de Configuración
	cargarArchivoConfiguracion(argv[1]);
	//Me conecto con la plataforma para despues de terminar todos los niveles correctamente avisarle
	socketOrquestador = connectToServer(ip_plataforma, atoi(puerto_orq), logger);
	log_debug(logger, "El personaje se conecto con el orquestador");

	//vuelve a tirar todos los hilos por todos los niveles

	do {
		log_debug(logger, "Tiro los hilos para jugar en cada nivel");

		reiniciar = false;

		crearTodosLosHilos();

		sem_wait(&semReinicio);
		sem_wait(&semFinPlan);
		//Ya terminaron todos los hilos. Si murio el ultimo me va a decir que reinicie o no.
		if (reiniciar) {
			liberarHilos();
			log_debug(logger, "El personaje %c termina su conexion y reinicia todos los niveles", personaje.simbolo);
		}

	} while (reiniciar);

	notificarFinPlanNiveles();

	cerrarConexion(&socketOrquestador);
	log_debug(logger, "El personaje se desconecto del orquestador");

	log_destroy(logger);
	config_destroy(configPersonaje);
	list_destroy_and_destroy_elements(personaje.lPersonajes, (void*) _liberar_personaje_individual);
	exit(EXIT_SUCCESS);

}
void leerEntradas()
{
	while (1)
	{
		fd_set nodosSelect;
		pthread_mutex_lock(&mNodos);
		nodosSelect = nodos;
		pthread_mutex_unlock(&mNodos);
		select(FD_SETSIZE, &nodosSelect, NULL, NULL, NULL);

		//Chequeo si salio del select por una nueva conexion
		if (FD_ISSET(desbloquearSelect[0], &nodosSelect))
		{
			char* dummy = malloc(1);
			int count = 1;
			while (count != 0)
			{
				read(desbloquearSelect[0], dummy, 1);
				ioctl(desbloquearSelect[0], FIONREAD, &count);
			}
			free(dummy);
		}

		//Chequeo los fd de las conexiones
		for (int i=0; i<conexiones->elements_count ;i++)
		{
			pthread_mutex_lock(&mConexiones);
			Conexion_t* conexion = list_get(conexiones,i);
			pthread_mutex_unlock(&mConexiones);
			if (conexion->sockfd < 0) continue;
			if (true != FD_ISSET(conexion->sockfd,&nodosSelect))
			{
				continue;
			}

			int estado;
			mensaje_t* mensaje = malloc(sizeof(mensaje_t));
			estado = recibir(conexion->sockfd, mensaje);
			if (estado == CONECTADO)
			{
				pthread_t tProcesar;
				argumentos_t* args = malloc(sizeof(argumentos_t));
				args->conexion = conexion;
				args->mensaje = mensaje;

				pthread_create(&tProcesar, NULL, procesarComandoRemoto, args);
				//ioctl(conexion->sockfd, FIONREAD, &count);
			} else
			{
				cerrarConexion(conexion);
				continue;
			}
		}
	}
}
void ServerSocketListener::_run() {

    SIG_Trap sigint_handler(SIGINT);
    SignalHandler::getInstance()->registrarHandler(SIGINT, &sigint_handler);

    colaDeEnvio.get();

    Logger::log(nombre + "_L", "Creo cl sender" , DEBUG);
    ServerSocketClSender sender(clientSocket, nombre);
    clientSender = sender.run();

    char buffer[BUFFSIZE];
    std::string peticion;

    Logger::log(nombre + "_L", "Mando CONN START a sender" , DEBUG);
    mensaje recibido;
    recibido.mtype = CONNECTION_START;
    recibido.socket = this->clientSocket;
    peticion = nombre + SEPARATOR + std::to_string(getpid());
    strcpy ( recibido.texto,peticion.c_str() );
    recibido.msize = peticion.size();
    colaDeEnvio.escribir(recibido);

    while(!sigint_handler.signalWasReceived()) {
        int bytesRecibidos = this->recibir ( static_cast<void*>(buffer),BUFFSIZE );
        if (!sigint_handler.signalWasReceived()) {
            peticion = buffer;
            peticion.resize(bytesRecibidos);
            std::string nickname = peticion.substr(0, peticion.find_first_of(":"));
            std::string message = peticion.substr(peticion.find_first_of(":")+2, peticion.size());
            //std::cout << "ServerListener: " << getpid() << ": dato recibido: '" << peticion << "'";
            //std::cout << ", de : " << clientSocket << std::endl;
            Logger::log(nombre + "_L", "recibi '" +
                peticion.substr(0, std::min((int)peticion.size()-1, 10)) +
                "...' de " + std::to_string(clientSocket) , DEBUG);

            if (nickname == EXIT_MESSAGE) {
                recibido.mtype = CONNECTION_END;
            } else if (nickname == "_client") {
                recibido.mtype = NICKNAME_REQ;
            } else if (nickname == SEPARATOR){
                recibido.mtype = GET_LOG;
            } else {
                recibido.mtype = TEXT;
            }
            recibido.socket = this->clientSocket;
            recibido.msize = message.size();
            strcpy ( recibido.texto,message.c_str() );
            recibido.nsize = nickname.size();
            strcpy ( recibido.nickname,nickname.c_str() );

            Logger::log(nombre + "_L", "Forwardeo a sender" , DEBUG);
            colaDeEnvio.escribir(recibido);

            if (nickname == EXIT_MESSAGE) {
                raise(SIGINT);
                kill(clientSender, SIGINT);
            }
        }
    }

    Logger::log(nombre + "_L", "Cierro todo" , DEBUG);
    kill(clientSender, SIGINT);
    cerrarConexion();
}