using System;
using System.Collections.Generic;

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


namespace AIRuntime.Runtime.Agents.Runtime
{
    /// <summary>
    /// Runtime services, restrictions, and provider settings
    /// available during one agent execution.
    /// </summary>
    public sealed class AgentRuntimeContext
    {
        public AgentRuntimeContext(
            AgentExecutionContext executionContext,
            IReadOnlyList<CapabilityDescriptor> capabilities)
        {
            ExecutionContext =
                executionContext ??
                throw new ArgumentNullException(
                    nameof(executionContext));


            Capabilities =
                capabilities ??
                throw new ArgumentNullException(
                    nameof(capabilities));


            Options =
                new AgentExecutionOptions(
                    ExecutionContext
                        .Definition
                        .Profile);


            ProviderOptions =
                new ProviderRequestOptions(
                    Options.Temperature,
                    Options.MaxTokens);
        }

        
        public AgentExecutionContext ExecutionContext
        {
            get;
        }


        public IReadOnlyList<CapabilityDescriptor> Capabilities
        {
            get;
        }


        /// <summary>
        /// Immutable runtime settings copied from the
        /// agent profile for this execution.
        /// </summary>
        public AgentExecutionOptions Options
        {
            get;
        }


        /// <summary>
        /// Generic provider request settings derived from
        /// the agent execution options.
        ///
        /// The provider layer does not need to know that
        /// these settings originated from an agent.
        /// </summary>
        public ProviderRequestOptions ProviderOptions
        {
            get;
        }


        public CapabilityAccessPolicy CapabilityPolicy
        {
            get
            {
                return ExecutionContext
                    .Definition
                    .CapabilityPolicy;
            }
        }
        public bool CanUseCapability(
            string capabilityName)
        {
            return CapabilityPolicy
                .CanUse(
                    capabilityName);
        }

        public string AgentId
        {
            get
            {
                return ExecutionContext.AgentId;
            }
        }


        public string SessionId
        {
            get
            {
                return ExecutionContext.SessionId;
            }
        }
    }
}