use crate::executors::RawCallResult;
use alloy_primitives::{
    Bytes, Log,
    map::{AddressHashMap, HashMap},
};
use foundry_evm_core::{Breakpoints, evm::FoundryEvmNetwork};
use foundry_evm_coverage::HitMaps;
use foundry_evm_fuzz::{BasicTxDetails, FuzzCase};
use foundry_evm_traces::SparsedTraceArena;
use revm::interpreter::InstructionResult;

/// Returned by a single fuzz in the case of a successful run
#[derive(Debug)]
pub struct CaseOutcome {
    /// Data of a single fuzz test case.
    pub case: FuzzCase,
    /// The traces of the call.
    pub traces: Option<SparsedTraceArena>,
    /// Runtime bytecodes for contracts seen in the trace.
    pub debug_bytecodes: AddressHashMap<Bytes>,
    /// The coverage info collected during the call.
    pub coverage: Option<HitMaps>,
    /// Breakpoints char pc map.
    pub breakpoints: Breakpoints,
    /// logs of a single fuzz test case.
    pub logs: Vec<Log>,
    // Deprecated cheatcodes mapped to their replacements.
    pub deprecated_cheatcodes: HashMap<&'static str, Option<&'static str>>,
}

/// Returned by a single fuzz when a counterexample has been discovered
#[derive(Debug)]
pub struct CounterExampleOutcome<FEN: FoundryEvmNetwork> {
    /// Minimal reproduction test case for failing test.
    pub counterexample: (BasicTxDetails, RawCallResult<FEN>),
    /// The status of the call.
    pub exit_reason: Option<InstructionResult>,
    /// Breakpoints char pc map.
    pub breakpoints: Breakpoints,
}

/// Outcome of a single fuzz
#[derive(Debug)]
#[expect(clippy::large_enum_variant)]
pub enum FuzzOutcome<FEN: FoundryEvmNetwork> {
    Case(CaseOutcome),
    CounterExample(CounterExampleOutcome<FEN>),
}
