using System;
using System.Collections.Generic;

using AIRuntime.Runtime.Agents;

using NUnit.Framework;


namespace AIRuntime.Tests
{
    public sealed class AgentRegistryTests
    {
        private AgentRegistry _registry;


        [SetUp]
        public void Setup()
        {
            _registry =
                new AgentRegistry();
        }


        [Test]
        public void Register_AddsAgent()
        {
            AgentDefinition agent =
                CreateAgent();


            _registry.Register(
                agent);


            Assert.AreEqual(
                1,
                _registry.Count);


            Assert.IsTrue(
                _registry.Contains(
                    "TestAgent"));
        }


        [Test]
        public void Get_ReturnsRegisteredAgent()
        {
            AgentDefinition agent =
                CreateAgent();


            _registry.Register(
                agent);


            AgentDefinition result =
                _registry.Get(
                    "TestAgent");


            Assert.AreSame(
                agent,
                result);
        }


        [Test]
        public void Get_UnknownAgentThrows()
        {
            Assert.Throws<KeyNotFoundException>(
                () =>
                {
                    _registry.Get(
                        "MissingAgent");
                });
        }


        [Test]
        public void Register_DuplicateAgentThrowsWithoutReplacingExistingAgent()
        {
            AgentDefinition first =
                new AgentDefinition(
                    "Architect",
                    "Version One",
                    "Architecture planning agent",
                    "Plan systems and create technical designs.");


            AgentDefinition second =
                new AgentDefinition(
                    "Architect",
                    "Version Two",
                    "Updated architecture agent",
                    "Create improved technical plans.");


            _registry.Register(
                first);


            InvalidOperationException exception =
                Assert.Throws<InvalidOperationException>(
                    () =>
                        _registry.Register(
                            second));


            StringAssert.Contains(
                "already registered",
                exception.Message);


            AgentDefinition result =
                _registry.Get(
                    "Architect");


            Assert.AreSame(
                first,
                result);


            Assert.AreEqual(
                1,
                _registry.Count);
        }


        [Test]
        public void Remove_RemovesAgent()
        {
            AgentDefinition agent =
                CreateAgent();


            _registry.Register(
                agent);


            bool removed =
                _registry.Remove(
                    "TestAgent");


            Assert.IsTrue(
                removed);


            Assert.IsFalse(
                _registry.Contains(
                    "TestAgent"));
        }


        [Test]
        public void Remove_MissingAgentReturnsFalse()
        {
            bool removed =
                _registry.Remove(
                    "Missing");


            Assert.IsFalse(
                removed);
        }


        [Test]
        public void GetAll_ReturnsRegisteredAgents()
        {
            _registry.Register(
                CreateAgent());


            Assert.AreEqual(
                1,
                _registry.GetAll().Count);
        }


        private static AgentDefinition CreateAgent()
        {
            return new AgentDefinition(
                "TestAgent",
                "Test Agent",
                "Testing agent",
                "Testing prompt");
        }
    }
}
