//! [TSM.ID].[11031972] — Platform X Ecosystem
//! Slab allocator with free-list management

use crate::{PoolConfig, PoolError, PoolStats, Result};

struct Block {
    data: Vec<u8>,
    in_use: bool,
}

pub struct SlabAllocator {
    blocks: Vec<Block>,
    free_list: Vec<usize>,
    block_size: usize,
    alloc_count: u64,
    free_count: u64,
    peak_usage: usize,
}

impl SlabAllocator {
    pub fn new(config: &PoolConfig) -> Result<Self> {
        if config.block_size == 0 || config.num_blocks == 0 {
            return Err(PoolError::InvalidBlockSize);
        }
        let aligned = (config.block_size + config.alignment - 1) & !(config.alignment - 1);
        let blocks: Vec<Block> = (0..config.num_blocks)
            .map(|_| Block { data: vec![0u8; aligned], in_use: false })
            .collect();
        let free_list: Vec<usize> = (0..config.num_blocks).rev().collect();
        Ok(Self { blocks, free_list, block_size: aligned, alloc_count: 0, free_count: 0, peak_usage: 0 })
    }

    pub fn allocate(&mut self) -> Result<(usize, &mut [u8])> {
        let idx = self.free_list.pop().ok_or(PoolError::PoolExhausted)?;
        self.blocks[idx].in_use = true;
        self.alloc_count += 1;
        let used = self.blocks.iter().filter(|b| b.in_use).count();
        if used > self.peak_usage { self.peak_usage = used; }
        let block = &mut self.blocks[idx];
        Ok((idx, &mut block.data))
    }

    pub fn deallocate(&mut self, idx: usize) -> Result<()> {
        if idx >= self.blocks.len() { return Err(PoolError::InvalidPointer); }
        if !self.blocks[idx].in_use { return Err(PoolError::DoubleFree); }
        self.blocks[idx].in_use = false;
        self.blocks[idx].data.fill(0);
        self.free_list.push(idx);
        self.free_count += 1;
        Ok(())
    }

    pub fn stats(&self) -> PoolStats {
        let used = self.blocks.iter().filter(|b| b.in_use).count();
        PoolStats {
            total_blocks: self.blocks.len(),
            used_blocks: used,
            free_blocks: self.blocks.len() - used,
            total_bytes: self.blocks.len() * self.block_size,
            used_bytes: used * self.block_size,
            peak_usage: self.peak_usage,
            alloc_count: self.alloc_count,
            free_count: self.free_count,
        }
    }
}
