using ZB.MOM.WW.ScadaBridge.Commons.Types;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening;

namespace ZB.MOM.WW.ScadaBridge.DeploymentManager;

/// <summary>
/// Abstraction over the TemplateEngine flattening + validation + hashing pipeline.
/// Used by DeploymentService to obtain a validated, hashed FlattenedConfiguration.
/// </summary>
public interface IFlatteningPipeline
{
    /// <summary>
    /// Flattens and validates an instance configuration, returning the configuration,
    /// revision hash, and validation result.
    /// </summary>
    /// <param name="instanceId">Id of the instance to flatten and validate.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <param name="validateScripts">
    /// When <c>true</c> (the deploy default), the authoritative Roslyn script-compilation
    /// gate runs. When <c>false</c>, that compile step is skipped — used by the read-only
    /// staleness/comparison paths (Deployments comparison page,
    /// <see cref="ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Transport.IStaleInstanceProbe"/>)
    /// which need only the flattened config + revision hash, not a compile. Structural and
    /// semantic validation still run in both cases.
    /// </param>
    /// <param name="session">
    /// Optional flatten session memoising template-chain, composition and
    /// session-global repository reads. Pass one shared session when flattening
    /// several instances in a batch (see <c>DeploymentService.DeploySiteAsync</c>)
    /// so a template chain shared by N instances is walked once. When
    /// <see langword="null"/> the pipeline creates a private single-use session,
    /// which still de-duplicates the repeated composed-chain loads inside one
    /// instance's flatten. Additive parameter — existing callers are unaffected.
    /// </param>
    /// <returns>A task that resolves to the flattened configuration, revision hash, and validation result; or a failure result if flattening could not complete.</returns>
    Task<Result<FlatteningPipelineResult>> FlattenAndValidateAsync(
        int instanceId,
        CancellationToken cancellationToken = default,
        bool validateScripts = true,
        FlattenSession? session = null);

    /// <summary>
    /// Creates a fresh <see cref="FlattenSession"/> bound to this pipeline's
    /// watermark, for a caller that wants to share one across a batch of
    /// <see cref="FlattenAndValidateAsync"/> calls.
    /// </summary>
    /// <returns>A new, empty session.</returns>
    FlattenSession CreateSession();
}

/// <summary>
/// Result of the flattening pipeline: configuration, hash, and validation.
/// </summary>
public record FlatteningPipelineResult(
    FlattenedConfiguration Configuration,
    string RevisionHash,
    ValidationResult Validation);
