//! Test suite for IngestWorker.
//!
//! Tests are organized by concern:
//! - `basic`: Basic record ingestion functionality
//! - `recovery`: WAL crash recovery and persistence
//! - `signatures`: Signature verification and rejection
//! - `cursor`: Cursor persistence and recovery
//! - `validation`: Input validation (confidence, weights, sizes, timestamps)
//! - `epoch_cascade`: Epoch supersession cascade logic
//! - `integration`: Large-scale integration tests

use super::*;
use ed25519_dalek::{Signer, SigningKey};
use rand::rngs::OsRng;
use std::sync::Arc;
use stemedb_core::testing::{self, AssertionBuilder};
use stemedb_core::types::{
    Assertion, Epoch, HlcTimestamp, LifecycleStage, ObjectValue, SignatureEntry, SourceClass, Vote,
};
use stemedb_storage::HybridStore;
use stemedb_wal::Journal;
use tempfile::tempdir;
use tokio::sync::Mutex;

mod basic;
mod cursor;
mod epoch_cascade;
mod integration;
mod recovery;
mod signatures;
mod validation;
mod validation_boundaries;

/// Create a properly signed test assertion.
///
/// Generates a fresh Ed25519 keypair and signs the subject:predicate message.
#[allow(dead_code)]
pub(super) fn create_test_assertion() -> Assertion {
    create_signed_assertion("Tesla_Inc", "has_revenue")
}

/// Create a signed assertion with custom subject and predicate.
#[allow(dead_code)]
pub(super) fn create_signed_assertion(subject: &str, predicate: &str) -> Assertion {
    let mut csprng = OsRng;
    let signing_key = SigningKey::generate(&mut csprng);
    let verifying_key = signing_key.verifying_key();

    let message = format!("{}:{}", subject, predicate);
    let signature = signing_key.sign(message.as_bytes());

    AssertionBuilder::new()
        .subject(subject)
        .predicate(predicate)
        .object_number(96.7)
        .confidence(0.95)
        .lifecycle(LifecycleStage::Proposed)
        .signatures(vec![SignatureEntry {
            version: 1,
            agent_id: verifying_key.to_bytes(),
            signature: signature.to_bytes(),
            timestamp: 1000,
        }])
        .build()
}

#[allow(dead_code)]
pub(super) fn create_test_vote() -> Vote {
    testing::test_vote([1u8; 32], [2u8; 32], 0.8, 2000)
}

#[allow(dead_code)]
pub(super) fn create_test_epoch() -> Epoch {
    let mut epoch = testing::test_epoch();
    epoch.start_timestamp = 3000;
    epoch
}
