using System;
using System.Collections.Generic;

using AIRuntime.Runtime.Agents;


namespace AIRuntime.Runtime.Agents.Runtime
{
    /// <summary>
    /// Creates and tracks runtime agent sessions.
    /// </summary>
    public sealed class AgentSessionManager
    {
        private readonly AgentRegistry _registry;


        private readonly Dictionary<string, AgentSession> _sessions =
            new Dictionary<string, AgentSession>();


        public AgentSessionManager(
            AgentRegistry registry)
        {
            _registry =
                registry ?? 
                throw new ArgumentNullException(
                    nameof(registry));
        }


        public int SessionCount
        {
            get
            {
                return _sessions.Count;
            }
        }


        public AgentSession CreateSession(
            string agentId)
        {
            if (string.IsNullOrWhiteSpace(agentId))
            {
                throw new ArgumentException(
                    "Agent id cannot be empty.",
                    nameof(agentId));
            }


            AgentDefinition definition;

            try
            {
                definition =
                    _registry.Get(
                        agentId);
            }
            catch (KeyNotFoundException exception)
            {
                throw new InvalidOperationException(
                    $"Agent '{agentId}' does not exist.",
                    exception);
            }


            AgentSession session =
                new AgentSession(
                    definition);


            _sessions.Add(
                session.SessionId,
                session);


            return session;
        }


        public AgentSession GetSession(
            string sessionId)
        {
            if (string.IsNullOrWhiteSpace(sessionId))
            {
                throw new ArgumentException(
                    "Session id cannot be empty.",
                    nameof(sessionId));
            }


            if (
                !_sessions.TryGetValue(
                    sessionId,
                    out AgentSession session))
            {
                throw new KeyNotFoundException(
                    $"Session '{sessionId}' does not exist.");
            }


            return session;
        }


        public bool RemoveSession(
            string sessionId)
        {
            return _sessions.Remove(
                sessionId);
        }
    }
}