using System;
using System.Collections.Generic;
using AIRuntime.Runtime.Agents;
using AIRuntime.Runtime.Agents.BuiltIn;
using AIRuntime.Runtime.Agents.Runtime;

using NUnit.Framework;


namespace AIRuntime.Tests
{
    public sealed class AgentSessionTests
    {
        //--------------------------------------------------
        // AgentSession
        //--------------------------------------------------

        [Test]
        public void Session_CreatesFromDefinition()
        {
            AgentDefinition definition =
                ArchitectAgentDefinition.Create();


            AgentSession session =
                new AgentSession(
                    definition);


            Assert.AreSame(
                definition,
                session.Definition);


            Assert.IsFalse(
                string.IsNullOrWhiteSpace(
                    session.SessionId));
        }



        [Test]
        public void Session_HasUniqueId()
        {
            AgentDefinition definition =
                ArchitectAgentDefinition.Create();


            AgentSession first =
                new AgentSession(
                    definition);


            AgentSession second =
                new AgentSession(
                    definition);


            Assert.AreNotEqual(
                first.SessionId,
                second.SessionId);
        }



        [Test]
        public void Session_RecordsExecution()
        {
            AgentDefinition definition =
                ArchitectAgentDefinition.Create();


            AgentSession session =
                new AgentSession(
                    definition);


            Assert.AreEqual(
                0,
                session.ExecutionCount);


            session.RecordExecution();


            Assert.AreEqual(
                1,
                session.ExecutionCount);


            session.RecordExecution();


            Assert.AreEqual(
                2,
                session.ExecutionCount);
        }



        //--------------------------------------------------
        // AgentSessionManager
        //--------------------------------------------------

        [Test]
        public void Manager_CreatesSession()
        {
            AgentRegistry registry =
                new AgentRegistry();


            AgentDefinition definition =
                ArchitectAgentDefinition.Create();


            registry.Register(
                definition);


            AgentSessionManager manager =
                new AgentSessionManager(
                    registry);


            AgentSession session =
                manager.CreateSession(
                    "ArchitectAgent");


            Assert.AreSame(
                definition,
                session.Definition);


            Assert.AreEqual(
                1,
                manager.SessionCount);
        }


        [Test]
        public void Manager_UnknownAgentThrows()
        {
            AgentRegistry registry =
                new AgentRegistry();


            AgentSessionManager manager =
                new AgentSessionManager(
                    registry);


            InvalidOperationException exception =
                Assert.Throws<InvalidOperationException>(
                    () =>
                    {
                        manager.CreateSession(
                            "MissingAgent");
                    });


            StringAssert.Contains(
                "MissingAgent",
                exception.Message);
        }


        [Test]
        public void Manager_GetSessionReturnsCreatedSession()
        {
            AgentRegistry registry =
                new AgentRegistry();


            registry.Register(
                DeveloperAgentDefinition.Create());


            AgentSessionManager manager =
                new AgentSessionManager(
                    registry);


            AgentSession created =
                manager.CreateSession(
                    "DeveloperAgent");


            AgentSession result =
                manager.GetSession(
                    created.SessionId);


            Assert.AreSame(
                created,
                result);
        }



        [Test]
        public void Manager_RemoveUnknownSessionReturnsFalse()
        {
            AgentRegistry registry =
                new AgentRegistry();


            AgentSessionManager manager =
                new AgentSessionManager(
                    registry);


            bool removed =
                manager.RemoveSession(
                    "missing-session");


            Assert.IsFalse(
                removed);
        }
    }
}