//! Pipeline data types.

use std::collections::{BTreeMap, BTreeSet};
use std::path::PathBuf;

use crate::types::broker::ReconciledFile;
use crate::types::config::ConfigError;
use crate::types::report;

pub(crate) type ReconciledFiles = Vec<ReconciledFile>;
pub(crate) type ReconcileResult = Result<ReconcileState, AbortReason>;
pub(crate) type PendingFileWrite = (PathBuf, Vec<u8>);
pub(crate) type PendingFileWrites = Vec<PendingFileWrite>;
pub(crate) type RunnerFindings = Vec<report::Finding>;
pub(crate) type RunnerFindingResult = Result<RunnerFindings, AbortReason>;
pub(crate) type RustfmtConfigNamesByDirectory<'a> = BTreeMap<String, BTreeSet<&'a str>>;
pub(crate) type UsedAdapterIds = BTreeSet<&'static str>;

/// Output of policy/adapter/engine reconciliation.
#[derive(Debug)]
pub(crate) struct ReconcileState {
    /// One reconciled file per engine that received requirements.
    pub files: ReconciledFiles,
    /// Adapter ids used by enabled policies in this run.
    pub used_adapters: UsedAdapterIds,
}

/// Why a run aborted.
#[derive(Debug, Clone)]
pub enum AbortReason {
    /// The config could not be loaded or resolved.
    Config(ConfigError),
    /// A policy rejected its params.
    Policy { policy: String, detail: String },
    /// A managed file could not be read, or its engine was unregistered.
    Broker(String),
    /// The default `shakrs.json` scaffold could not be written.
    Scaffold(String),
    /// A policy emitted a requirement for an unregistered adapter id.
    UnknownAdapter(String),
    /// An adapter rejected a requirement routed to it.
    Adapter(String),
}

/// What an `init` run wrote.
#[derive(Debug, Default)]
pub struct InitWrites {
    /// Files written.
    pub written: Vec<String>,
    /// Files skipped because they carried hard-failure findings.
    pub skipped: Vec<String>,
    /// True when a default `shakrs.json` was scaffolded.
    pub scaffolded: bool,
    /// Findings encountered while reconciling.
    pub findings: Vec<report::Finding>,
    /// Adapter validation command failures.
    pub validation_command_failures: Vec<report::ValidationCommandFailure>,
}
