use std::collections::HashMap;

pub use fabro_types::checkpoint::Checkpoint;
use fabro_types::failure_signature::FailureSignature;

use crate::artifact;
use crate::context::Context;
use crate::outcome::Outcome;

pub trait CheckpointExt {
    fn from_context(
        context: &Context,
        current_node: &str,
        completed_nodes: Vec<String>,
        node_retries: HashMap<String, u32>,
        node_outcomes: HashMap<String, Outcome>,
        next_node_id: Option<String>,
        loop_failure_signatures: HashMap<FailureSignature, usize>,
        restart_failure_signatures: HashMap<FailureSignature, usize>,
        node_visits: HashMap<String, usize>,
    ) -> Self;
}

impl CheckpointExt for Checkpoint {
    fn from_context(
        context: &Context,
        current_node: &str,
        completed_nodes: Vec<String>,
        node_retries: HashMap<String, u32>,
        mut node_outcomes: HashMap<String, Outcome>,
        next_node_id: Option<String>,
        loop_failure_signatures: HashMap<FailureSignature, usize>,
        restart_failure_signatures: HashMap<FailureSignature, usize>,
        node_visits: HashMap<String, usize>,
    ) -> Self {
        artifact::normalize_durable_outcomes(&mut node_outcomes);

        Self {
            timestamp: chrono::Utc::now(),
            current_node: current_node.to_string(),
            completed_nodes,
            node_retries,
            context_values: artifact::durable_context_snapshot(context),
            node_outcomes,
            next_node_id,
            git_commit_sha: None,
            loop_failure_signatures,
            restart_failure_signatures,
            node_visits,
        }
    }
}
