// Copyright (c) 2025 TerraByte Inc.
//
// Defines the public interface for a Promise, which represents the eventual
// completion (or failure) of an asynchronous operation and its resulting value.
// This decouples the consumer from the implementation.

using System;

namespace Terra.Arbitrator.Promises
{
    public enum PromiseState { Pending, Resolved, Rejected }

    public interface IPromise<out TResult>
    {
        /// <summary>
        /// Attaches a callback that will execute when the promise is successfully resolved.
        /// </summary>
        IPromise<TResult> Then(Action<TResult> onResolved);
        
        /// <summary>
        /// Attaches a function that returns a new promise, allowing operations to be chained.
        /// The chain will wait until the returned promise is resolved before continuing.
        /// </summary>
        /// <returns>A new promise that resolves with the result of the chained promise.</returns>
        IPromise<TNewResult> Then<TNewResult>(Func<TResult, IPromise<TNewResult>> onResolved);
        
        /// <summary>
        /// Attaches a callback that will execute when the promise is rejected.
        /// </summary>
        IPromise<TResult> Catch(Action<Exception> onRejected);
        
        /// <summary>
        /// Attaches a callback that will execute when the promise is settled (either resolved or rejected).
        /// </summary>
        void Finally(Action onFinally);
    }
}