//! This module provides methods to trigger manual compaction of the database
//! to optimize storage and improve read performance. Compaction merges
//! sorted string tables (SSTables) and removes deleted entries.
use super::Database;
use super::slice::Slice;
use crate::binding::leveldb_compact_range;
use libc::{c_char, size_t};

/// Compaction operations for LevelDB database.
pub trait Compaction {
    /// Compact the database between start and limit keys (inclusive)
    fn compact(&self, start: Slice, limit: Slice);

    /// Compact the entire database
    fn compact_all(&self);

    /// Compact the database from start key to the end
    fn compact_from(&self, start: Slice);

    /// Compact the database from the beginning to limit key
    fn compact_until(&self, limit: Slice);
}

impl Compaction for Database {
    fn compact(&self, start: Slice, limit: Slice) {
        unsafe {
            let start_bytes = start.as_bytes();
            let limit_bytes = limit.as_bytes();
            leveldb_compact_range(
                self.database.ptr,
                start_bytes.as_ptr() as *mut c_char,
                start_bytes.len() as size_t,
                limit_bytes.as_ptr() as *mut c_char,
                limit_bytes.len() as size_t,
            )
        }
    }

    fn compact_all(&self) {
        unsafe {
            leveldb_compact_range(
                self.database.ptr,
                std::ptr::null(),
                0 as size_t,
                std::ptr::null(),
                0 as size_t,
            )
        }
    }

    fn compact_from(&self, start: Slice) {
        unsafe {
            let start_bytes = start.as_bytes();
            leveldb_compact_range(
                self.database.ptr,
                start_bytes.as_ptr() as *mut c_char,
                start_bytes.len() as size_t,
                std::ptr::null(),
                0 as size_t,
            )
        }
    }

    fn compact_until(&self, limit: Slice) {
        unsafe {
            let limit_bytes = limit.as_bytes();
            leveldb_compact_range(
                self.database.ptr,
                std::ptr::null(),
                0 as size_t,
                limit_bytes.as_ptr() as *mut c_char,
                limit_bytes.len() as size_t,
            )
        }
    }
}
