use crate::graph::tree::{ArtifactId, DependencyTree};
use crate::core::env::SpecmanEnv;
use crate::core::error::{LifecycleError, SpecmanError};
use crate::storage::persistence::{ArtifactRemovalStore, RemovedArtifact};

#[derive(Clone, Debug, Default)]
pub struct DeleteOptions {
    pub force: bool,
    pub dry_run: bool,
}

#[derive(Clone, Debug)]
pub enum DeleteResult {
    Removed(RemovedArtifact),
    DryRun(DeletePlan),
}

#[derive(Clone, Debug)]
pub struct DeletePlan {
    pub dependencies: DependencyTree,
    pub blocked: bool,
}

pub fn delete_artifact(
    env: &SpecmanEnv,
    target: &ArtifactId,
    opts: DeleteOptions,
) -> Result<DeleteResult, SpecmanError> {
    // [ENSURES: entity-lifecyclecontroller.requirements:CHECK]
    let dependencies = env.mapping.dependency_tree(target)?;
    let blocked = dependencies.has_blocking_dependents();

    if opts.dry_run {
        return Ok(DeleteResult::DryRun(DeletePlan {
            dependencies,
            blocked,
        }));
    }

    if blocked && !opts.force {
        return Err(LifecycleError::DeletionBlocked { target: target.clone() }.into());
    }

    let removed = env.persistence.remove_artifact(target)?;

    Ok(DeleteResult::Removed(removed))
}
