#pragma once

#include <map>
#include <string>
#include <winscard.h>
#include "cryptoki.h"
#include "Session.h"
#include "Pkcs11Exceptions.h"

using namespace std;


/********************************************************************************************

********************************************************************************************/
class CSessionList
{

	public:

		// Método que genera la única instancia de la clase y devuelve una referencia a la misma
		static CSessionList & getInstance()
		{
			static CSessionList rObjectList;
			return rObjectList;
		}

		// Destructor
		~CSessionList(void);

		// Método que actualiza la lista de objetos del equipo
		//void Update(void);
		
		// Método para insertar una nueva sesión PKCS#11 en un slot determinado en la lista de sesiones abiertas
		void Add(CK_SLOT_ID slotID, CSession *pSession);

		//  Método para eliminar un handle de sessión, y si es necesario, eliminar también la sessión.
		//void Delete(CK_SESSION_HANDLE hSession, CSession *pSession = NULL );
		void DeleteHandle(CK_SESSION_HANDLE hSession);

		// Método para eliminar una sesión y todos sus handles
		void DeleteSessionAndHandles(CK_SESSION_HANDLE hSession);

		// Método para eliminar todas las sesiones y todos los handles de un slot
		void DeleteAllSessionsAndHandles( CK_SLOT_ID slotId );

		// Método para devolver el número de sesiones abiertas
		unsigned long GetNumberOfSessions();

		// Método para comprobar y devolver el objeto sesión, en caso de que exista
		CSession * FindSession(CK_SESSION_HANDLE hSession);

		// Método para comprobar y devolver el objeto sesión de un determinado slot, en caso de que exista
		CSession * FindSessionInSlot(CK_SLOT_ID slotID);

		// Método para indicar si existe sesión en un determinado slot
		bool ExistSessionInSlot(CK_SLOT_ID slotID);

		// Método que obtiene un nuevo handle de sesión
		CK_SESSION_HANDLE GetNewSessionHandle(CK_SLOT_ID slotID);
		
		// Método que resetea el estado de seguridad de todas las sesiones del mismo Slot
		void ResetSessionsInSlot(CK_SESSION_HANDLE hSession);

		// Método que obtiene el número de objetos según la última actualización de la lista
		//unsigned long GetNumberOfSlots(bool bSupportedTokenPresent);

		// Método que genera una lista de los IDs de objetos según la última actualización de la lista
		//void GetSlots(unsigned long * pulSlots, bool bTokenPresent);
		
		// Método que obtiene el lector con un determinado ID
		//CSlot GetSlot(unsigned long ulId);
		
	private:

		// Lista de objetos detectados la última vez en el equipo, identificados por su ID
		map<CK_SLOT_ID, CSession *> m_mapSlot2Session;
		map<CK_SESSION_HANDLE, CK_SLOT_ID> m_mapHandle2Slot;

		// Próximo ID a asignar
		CK_SESSION_HANDLE m_ulNextId;

		// Constructor privado, dado que es una clase singleton
		CSessionList(void);
};
