#ifndef ADMIN_API_C
#define ADMIN_API_C

#include <API.h>
#include <config.h>
#include <semaforos.h>
#include <mem_compartida.h>
#include <stdio.h>
#include <string.h>

// Devuelve NULL sii hubo un error en el pedido del recurso
char* pedir_recurso (
		char* clave_proceso, // clave de proceso (entrada)
		char *clave_recurso, // clave de recurso (entrada)
		int* tamano_recurso, // tamano del recurso (salida)
		int* codigo_retorno  // codigo de retorno (salida)
) {
	int sem_id,shm_id;
	struct memoria_compartida *mem;
	char *recurso_datos;
	sem_id = obtenerSemaforos();
	shm_id = obtenerMemoria();
	mem    = (struct memoria_compartida *) ptrMemoria(shm_id);

	P(sem_id,SEM_ADMIN);

	// Escribo en memoria...
	mem->oper=OP_PEDIR_RECURSO;
	strcpy(mem->clave,clave_proceso);
	strcpy(mem->desc, clave_recurso);
		
	V(sem_id,SEM_MEMORIA);
 	P(sem_id,SEM_RESPUESTA);
	if (mem->oper == RESPUESTA_OK) {
		// copiar en tamano_recurso el largo del str
		// codigo de retorno
		recurso_datos = (char*) ptrMemoria(mem->shm_id);
		*tamano_recurso = strlen(recurso_datos)+1;
		*codigo_retorno = RECURSO_OK;
	} else {
		// Me fijo el tipo de error que devuelve el adminso
		// y lo paso al proceso
		switch (mem->error) {
			case ERROR_RECURSO_NOEXISTE:	
				*codigo_retorno = RECURSO_ERROR_NOEXISTE;
				break;
			case ERROR_RECURSO_PEDIDO:
				*codigo_retorno = RECURSO_ERROR_PEDIDO;
				break;
			case ERROR_RECURSO_MAX_POR_PROCESO:
			   *codigo_retorno = RECURSO_ERROR_MAX_POR_PROCESO;
				break;
			default:
				*codigo_retorno = -1;
				break;
		}
		recurso_datos = NULL;
	}
 	V(sem_id,SEM_ADMIN);
	return recurso_datos;
}

// Libera el recurso adquirido por el proceso

void liberar_recurso(

	char* clave_proceso,	// clave de proceso (entrada)
	char* clave_recurso,	// clave de recurso (entrada)
	char* recurso,			// recurso asignado (entrada)
	int* codigo_retorno		// codigo de retorno (salida)

) {
	int sem_id,shm_id;
	struct memoria_compartida *mem;

	sem_id = obtenerSemaforos();
	shm_id = obtenerMemoria();
	mem    = (struct memoria_compartida *) ptrMemoria(shm_id);

	P(sem_id,SEM_ADMIN);

	// Escribo en memoria...
	mem->oper=OP_LIBERAR_RECURSO;
	
	strcpy(mem->clave,clave_proceso);
	strcpy(mem->desc, clave_recurso);
	
	V(sem_id,SEM_MEMORIA);
 	P(sem_id,SEM_RESPUESTA); //espero que el adminso me de una respuesta
	if (mem->oper == RESPUESTA_OK) {
		borrarMemoria(recurso); //saco de memoria este recurso del proceso que lo pidio
		*codigo_retorno = RECURSO_OK;
		
	} else {
		// Me fijo el tipo de error que devuelve el adminso
		// y lo paso al proceso
		switch (mem->error) {
			case ERROR_RECURSO_NOEXISTE:	
				*codigo_retorno = RECURSO_ERROR_NOEXISTE;
			break;
			case ERROR_RECURSO_PEDIDO:
				*codigo_retorno = RECURSO_ERROR_PEDIDO;
			break;
			case ERROR_RECURSO_NO_ES_TUYO:
				*codigo_retorno = RECURSO_ERROR_NO_ES_TUYO;
			break;
			default:
				*codigo_retorno = -1;
			break;
		}
	}
 	V(sem_id,SEM_ADMIN);
}




#endif
