//! Implementation of the MdfWriter struct split across several submodules

use std::io::{Write, Seek};

trait WriteSeek: Write + Seek {}
impl<T: Write + Seek> WriteSeek for T {}
use std::collections::HashMap;

use crate::blocks::channel_block::ChannelBlock;
use crate::error::MdfError;
use crate::writer::mdf_writer::data::ChannelEncoder;

mod io;
mod init;
pub mod data;

/// Helper structure tracking an open DTBLOCK during writing
struct OpenDataBlock {
    dg_id: String,
    dt_id: String,
    start_pos: u64,
    record_size: usize,
    record_count: u64,
    /// Total number of records written across all DT blocks for this group
    total_record_count: u64,
    channels: Vec<ChannelBlock>,
    dt_ids: Vec<String>,
    dt_positions: Vec<u64>,
    dt_sizes: Vec<u64>,
    /// Scratch buffer reused for record encoding
    record_buf: Vec<u8>,
    /// Template filled with constant values used to initialise each record
    record_template: Vec<u8>,
    /// Precomputed per-channel encoders
    encoders: Vec<ChannelEncoder>,
}

/// Writer for MDF blocks, ensuring 8-byte alignment and zero padding.
/// Tracks block positions and supports updating links at a later stage.
pub struct MdfWriter {
    file: Box<dyn WriteSeek>,
    offset: u64,
    block_positions: HashMap<String, u64>,
    open_dts: HashMap<String, OpenDataBlock>,
    dt_counter: usize,
    last_dg: Option<String>,
    cg_to_dg: HashMap<String, String>,
    cg_offsets: HashMap<String, usize>,
    cg_channels: HashMap<String, Vec<ChannelBlock>>,
    channel_map: HashMap<String, (String, usize)>,
}
