using System;
using System.Collections.Generic;

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

using NUnit.Framework;


namespace AIRuntime.Tests
{
    public sealed class ProviderRequestOptionsTests
    {
        [Test]
        public void Constructor_AssignsValues()
        {
            ProviderRequestOptions options =
                new ProviderRequestOptions(
                    0.75,
                    8192);


            Assert.AreEqual(
                0.75,
                options.Temperature);


            Assert.AreEqual(
                8192,
                options.MaxTokens);
        }


        [Test]
        public void Default_ReturnsExpectedSettings()
        {
            ProviderRequestOptions options =
                ProviderRequestOptions.Default;


            Assert.AreEqual(
                0.2,
                options.Temperature);


            Assert.AreEqual(
                0,
                options.MaxTokens);
        }


        [Test]
        public void NegativeTemperature_Throws()
        {
            Assert.Throws<ArgumentOutOfRangeException>(
                () =>
                {
                    new ProviderRequestOptions(
                        -0.1,
                        4096);
                });
        }


        [Test]
        public void InvalidTemperature_Throws()
        {
            Assert.Throws<ArgumentOutOfRangeException>(
                () =>
                {
                    new ProviderRequestOptions(
                        double.NaN,
                        4096);
                });


            Assert.Throws<ArgumentOutOfRangeException>(
                () =>
                {
                    new ProviderRequestOptions(
                        double.PositiveInfinity,
                        4096);
                });
        }


        [Test]
        public void ZeroMaxTokens_UsesProviderNativeLimit()
        {
            ProviderRequestOptions options =
                new ProviderRequestOptions(
                    0.2,
                    0);

            Assert.AreEqual(
                0,
                options.MaxTokens);
        }


        [Test]
        public void RuntimeContext_ConvertsAgentSettings()
        {
            AgentDefinition definition =
                new AgentDefinition(
                    "DeveloperAgent",
                    "Developer Agent",
                    "",
                    "");


            definition.Profile.Temperature =
                0.55;


            definition.Profile.MaxTokens =
                7000;


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


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


            Assert.IsNotNull(
                runtimeContext.ProviderOptions);


            Assert.AreEqual(
                0.55,
                runtimeContext.ProviderOptions.Temperature);


            Assert.AreEqual(
                7000,
                runtimeContext.ProviderOptions.MaxTokens);
        }


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


            definition.Profile.Temperature =
                0.3;


            definition.Profile.MaxTokens =
                5000;


            AgentRuntimeContext runtimeContext =
                new AgentRuntimeContext(
                    new AgentExecutionContext(
                        new AgentSession(
                            definition)),
                    new List<CapabilityDescriptor>());


            definition.Profile.Temperature =
                0.9;


            definition.Profile.MaxTokens =
                12000;


            Assert.AreEqual(
                0.3,
                runtimeContext.ProviderOptions.Temperature);


            Assert.AreEqual(
                5000,
                runtimeContext.ProviderOptions.MaxTokens);
        }
    }
}
