using System.Collections.Generic;

using AIRuntime.Runtime.Agents;
using AIRuntime.Runtime.Agents.Runtime;
using AIRuntime.Runtime.Capabilities;

using NUnit.Framework;


namespace AIRuntime.Tests
{
    public sealed class AgentExecutionOptionsTests
    {
        [Test]
        public void Options_CopyAgentProfileSettings()
        {
            AgentProfile profile =
                new AgentProfile(
                    "DeveloperAgent");


            profile.Temperature =
                0.65;


            profile.MaxTokens =
                8192;


            profile.AddPreferredProvider(
                "LocalProvider");


            profile.AddPreferredProvider(
                "CloudFallback");


            AgentExecutionOptions options =
                new AgentExecutionOptions(
                    profile);


            Assert.AreEqual(
                "DeveloperAgent",
                options.AgentId);


            Assert.AreEqual(
                0.65,
                options.Temperature);


            Assert.AreEqual(
                8192,
                options.MaxTokens);


            Assert.AreEqual(
                2,
                options.PreferredProviders.Count);


            Assert.AreEqual(
                "LocalProvider",
                options.PreferredProviders[0]);


            Assert.AreEqual(
                "CloudFallback",
                options.PreferredProviders[1]);


            Assert.IsTrue(
                options.HasPreferredProviders);
        }


        [Test]
        public void Options_AreSnapshotOfProfile()
        {
            AgentProfile profile =
                new AgentProfile(
                    "TestingAgent");


            profile.Temperature =
                0.1;


            profile.MaxTokens =
                2048;


            profile.AddPreferredProvider(
                "InitialProvider");


            AgentExecutionOptions options =
                new AgentExecutionOptions(
                    profile);


            //--------------------------------------------------
            // Change the original profile after taking
            // the execution snapshot.
            //--------------------------------------------------

            profile.Temperature =
                0.9;


            profile.MaxTokens =
                16384;


            profile.AddPreferredProvider(
                "LaterProvider");


            Assert.AreEqual(
                0.1,
                options.Temperature);


            Assert.AreEqual(
                2048,
                options.MaxTokens);


            Assert.AreEqual(
                1,
                options.PreferredProviders.Count);


            Assert.AreEqual(
                "InitialProvider",
                options.PreferredProviders[0]);
        }


        [Test]
        public void RuntimeContext_ContainsProfileOptions()
        {
            AgentDefinition definition =
                new AgentDefinition(
                    "ReviewAgent",
                    "Review Agent",
                    "",
                    "");


            definition.Profile.Temperature =
                0.25;


            definition.Profile.MaxTokens =
                6000;


            definition.Profile.AddPreferredProvider(
                "ReviewProvider");


            AgentExecutionContext executionContext =
                new AgentExecutionContext(
                    new AgentSession(
                        definition));


            AgentRuntimeContext runtimeContext =
                new AgentRuntimeContext(
                    executionContext,
                    new List<CapabilityDescriptor>());


            Assert.IsNotNull(
                runtimeContext.Options);


            Assert.AreEqual(
                "ReviewAgent",
                runtimeContext.Options.AgentId);


            Assert.AreEqual(
                0.25,
                runtimeContext.Options.Temperature);


            Assert.AreEqual(
                6000,
                runtimeContext.Options.MaxTokens);


            Assert.AreEqual(
                "ReviewProvider",
                runtimeContext.Options.PreferredProviders[0]);
        }


        [Test]
        public void Options_WithNoProvidersReportsFalse()
        {
            AgentExecutionOptions options =
                new AgentExecutionOptions(
                    new AgentProfile(
                        "EmptyAgent"));


            Assert.IsFalse(
                options.HasPreferredProviders);


            Assert.AreEqual(
                0,
                options.PreferredProviders.Count);
        }


        [Test]
        public void NullProfile_Throws()
        {
            Assert.Throws<System.ArgumentNullException>(
                () =>
                {
                    new AgentExecutionOptions(
                        null);
                });
        }
    }
}