using System;
using System.Collections.Generic;
using System.Threading.Tasks;

using Newtonsoft.Json.Linq;

using AIRuntime.Runtime.Capabilities.Permissions;


namespace AIRuntime.Runtime.Capabilities
{
    /// <summary>
    /// Controls how calls to one capability may be grouped in a single
    /// provider response. Capabilities opt in only when their implementation
    /// owns the ordering and validation required for a batch.
    /// </summary>
    public enum CapabilityBatchBehavior
    {
        SingleMutationPerResponse = 0,

        AllowSameCapabilityBatch = 1
    }


    /// <summary>
    /// Controls what the conversation engine does when a provider repeatedly
    /// requests an identical mutation that has already completed.
    /// </summary>
    public enum CapabilityRepeatedCallBehavior
    {
        ReplayPreviousResult = 0,

        CompleteRunFromPreviousResult = 1
    }


    /// <summary>
    /// Controls whether an observation may be safely reused while no
    /// capability mutation has occurred. Volatile observations continue to
    /// execute on every request; stable observations participate in the
    /// conversation engine's semantic no-progress guard.
    /// </summary>
    public enum CapabilityObservationBehavior
    {
        Volatile = 0,

        StableUntilMutation = 1
    }


    /// <summary>
    /// Optional metadata for read-only capabilities whose result remains
    /// authoritative until a capability mutates run state.
    /// </summary>
    public interface ICapabilityObservationSemantics
    {
        CapabilityObservationBehavior ObservationBehavior
        {
            get;
        }
    }


    /// <summary>
    /// Optional execution metadata for capabilities whose safe orchestration
    /// differs from the conservative runtime defaults.
    ///
    /// The conversation engine must reason from these generic semantics rather
    /// than from application-specific capability names.
    /// </summary>
    public interface ICapabilityExecutionSemantics
    {
        CapabilityBatchBehavior BatchBehavior
        {
            get;
        }


        CapabilityRepeatedCallBehavior RepeatedCallBehavior
        {
            get;
        }
    }


    /// <summary>
    /// Optional authorization metadata for capabilities whose effects span
    /// more than their legacy primary permission. Existing capabilities keep
    /// the single Permission contract; effect-aware capabilities can require
    /// every permission in this set before any business logic executes.
    /// </summary>
    public interface ICapabilityAuthorizationSemantics
    {
        IReadOnlyList<CapabilityPermission> RequiredPermissions
        {
            get;
        }

        IReadOnlyList<string> EffectScopes
        {
            get;
        }
    }


    /// <summary>
    /// Represents a capability that can be executed by AIRuntime.
    ///
    /// The runtime is responsible for:
    /// • Deserializing arguments
    /// • Validating arguments
    /// • Middleware execution
    /// • Providing the execution context
    /// • Serializing results
    ///
    /// A capability should only implement its own business logic.
    /// </summary>
    public interface ICapability
    {
        /// <summary>
        /// Unique capability name.
        /// Example:
        ///     read_file
        ///     write_file
        ///     list_directory
        /// </summary>
        string Name
        {
            get;
        }


        /// <summary>
        /// Human-readable description.
        /// Used by AI providers when advertising available tools.
        /// </summary>
        string Description
        {
            get;
        }


        /// <summary>
        /// Permission category required to execute this capability.
        /// </summary>
        CapabilityPermission Permission
        {
            get;
        }


        /// <summary>
        /// JSON Schema describing the capability arguments.
        /// Usually generated automatically by CapabilityBase&lt;TArguments&gt;.
        /// </summary>
        JObject Parameters
        {
            get;
        }


        /// <summary>
        /// CLR type representing the capability arguments.
        /// Used by the runtime for automatic deserialization.
        /// </summary>
        Type ArgumentType
        {
            get;
        }


        /// <summary>
        /// Runtime entry point.
        ///
        /// AIRuntime supplies the already-deserialized arguments
        /// together with the current execution context.
        ///
        /// Capabilities should not call this directly.
        /// </summary>
        Task<object> ExecuteObjectAsync(
            object arguments,
            CapabilityContext context);
    }
}
