pub mod engine_ffi;

use std::marker::PhantomData;

#[allow(improper_ctypes)]
unsafe extern "C" {
    fn SanCovRuntimeSetUpCoverageDomains(
        registry: *const engine_ffi::FuzzTestCoverageDomainRegistry,
    ) -> usize;

    fn SanCovRuntimeEmitFeatures(sink: *const engine_ffi::FuzzTestFeedbackSink);
}

/// A zero-sized witness token proving that a test is currently executing.
///
/// Some of the methods on FuzzTestDiagnosticSink require that they are called only if the engine is
/// calling `Execute` callback of FuzzTestAdapter, which includes:
///
/// * `emit_finding`
///
/// The methods receiving this type can safely assume that the `Execute` callback is active because
/// the caller ensures this by creating this type.
pub struct ExecuteContext {
    _private: PhantomData<()>,
}

impl ExecuteContext {
    /// Creates a new execution context.
    ///
    /// # Safety
    ///
    /// * The caller must ensure that it is in the `Execute` callback of FuzzTestAdapter.
    pub unsafe fn new() -> Self {
        Self { _private: PhantomData }
    }
}

#[derive(Clone)]
pub struct DiagnosticSink {
    raw: engine_ffi::FuzzTestDiagnosticSink,
}

impl DiagnosticSink {
    /// Creates a safe wrapper from a pointer to `FuzzTestDiagnosticSink`.
    ///
    /// # Safety
    ///
    /// The caller must ensure that:
    /// * `raw` is a non-null, properly aligned pointer to a valid `FuzzTestDiagnosticSink`.
    /// * `(*raw).ctx` is a valid context pointer.
    /// * The sink and its context remain valid for the duration of `DiagnosticSink`'s usage
    ///   (guaranteed by the engine until `FreeCtx` is called on the adapter).
    pub unsafe fn from_raw(raw: *const engine_ffi::FuzzTestDiagnosticSink) -> Self {
        // SAFETY: Caller guarantees `raw` is a valid pointer to `FuzzTestDiagnosticSink`.
        let raw_sink = unsafe { *raw };
        Self { raw: raw_sink }
    }

    /// Emits an unrecoverable error message to the underlying diagnostic sink.
    pub fn emit_error(&self, message: &str) {
        let emit = self.raw.emit_error.expect("EmitError is required by ABI");
        let view = engine_ffi::FuzzTestBytesView::from_bytes(message.as_bytes());
        // SAFETY: The presence of `self` guarantees that the context of the underlying
        // `FuzzTestDiagnosticSink` remains live for the duration of this sink.
        unsafe {
            emit(self.raw.ctx, &view);
        }
    }

    /// Emits a warning message to the underlying diagnostic sink.
    pub fn emit_warning(&self, message: &str) {
        let emit = self.raw.emit_warning.expect("EmitWarning is required by ABI");
        let view = engine_ffi::FuzzTestBytesView::from_bytes(message.as_bytes());
        // SAFETY: The presence of `self` guarantees that the context of the underlying
        // `FuzzTestDiagnosticSink` remains live for the duration of this sink.
        unsafe {
            emit(self.raw.ctx, &view);
        }
    }

    /// Emits a test finding (e.g., a crash or bug) to the underlying diagnostic sink.
    ///
    /// This must only be called during test execution, which is guaranteed by the
    /// [`ExecuteContext`] token.
    pub fn emit_finding(&self, _token: &ExecuteContext, description: &str, signature: &str) {
        let emit = self.raw.emit_finding.expect("EmitFinding is required by ABI");
        let desc_view = engine_ffi::FuzzTestBytesView::from_bytes(description.as_bytes());
        let sig_view = engine_ffi::FuzzTestBytesView::from_bytes(signature.as_bytes());
        // SAFETY: The presence of `self` guarantees that the context of the underlying
        // `FuzzTestDiagnosticSink` remains live for the duration of this sink.
        // The witness `_token` further proves execution is currently within the `Execute` callback.
        unsafe {
            emit(self.raw.ctx, &desc_view, &sig_view);
        }
    }
}

pub struct BytesSink {
    raw: engine_ffi::FuzzTestBytesSink,
}

impl BytesSink {
    /// Creates a safe wrapper from a pointer to `FuzzTestBytesSink`.
    ///
    /// # Safety
    ///
    /// The caller must ensure that:
    /// * `raw` is a non-null, properly aligned pointer to a valid `FuzzTestBytesSink`.
    /// * `(*raw).ctx` is a valid context pointer.
    /// * The sink and its context remain valid for the duration of `BytesSink`'s usage
    ///   (guaranteed by the engine until `FreeCtx` is called on the adapter).
    pub unsafe fn from_raw(raw: *const engine_ffi::FuzzTestBytesSink) -> Self {
        // SAFETY: Caller guarantees `raw` is a valid pointer to `FuzzTestBytesSink`.
        let raw_sink = unsafe { *raw };
        Self { raw: raw_sink }
    }

    /// Emits a byte slice to the underlying bytes sink.
    ///
    /// Multiple calls to this function will concatenate the emitted bytes.
    pub fn emit(&mut self, bytes: &[u8]) {
        let emit = self.raw.emit.expect("Emit is required by ABI");
        let view = engine_ffi::FuzzTestBytesView::from_bytes(bytes);
        // SAFETY: The presence of `self` guarantees `from_raw` was called with a valid context
        // pointer (`self.raw.ctx`) that remains live for the duration of this call.
        unsafe {
            emit(self.raw.ctx, &view);
        }
    }
}

pub struct InputSink {
    raw: engine_ffi::FuzzTestInputSink,
}

impl InputSink {
    /// Creates a safe wrapper from a pointer to `FuzzTestInputSink`.
    ///
    /// # Safety
    ///
    /// The caller must ensure that:
    /// * `raw` is a non-null, properly aligned pointer to a valid `FuzzTestInputSink`.
    /// * `(*raw).ctx` is a valid context pointer.
    /// * The sink and its context remain valid for the duration of `InputSink`'s usage
    ///   (guaranteed by the engine until `FreeCtx` is called on the adapter).
    pub unsafe fn from_raw(raw: *const engine_ffi::FuzzTestInputSink) -> Self {
        // SAFETY: Caller guarantees `raw` is a valid pointer to `FuzzTestInputSink`.
        let raw_sink = unsafe { *raw };
        Self { raw: raw_sink }
    }

    /// Emits a test input handle to the underlying input sink.
    ///
    /// This function transfers ownership of the input represented by the handle
    /// to the engine. The engine is responsible for freeing it.
    pub fn emit(&mut self, input: engine_ffi::FuzzTestInputHandle) {
        let emit = self.raw.emit.expect("Emit is required by ABI");
        // SAFETY: The presence of `self` guarantees `from_raw` was called with a valid context
        // pointer (`self.raw.ctx`) that remains live for the duration of this call.
        unsafe {
            emit(self.raw.ctx, input);
        }
    }
}

pub struct FeedbackSink {
    raw: engine_ffi::FuzzTestFeedbackSink,
}

impl FeedbackSink {
    /// Creates a safe wrapper from a pointer to `FuzzTestFeedbackSink`.
    ///
    /// # Safety
    ///
    /// The caller must ensure that:
    /// * `raw` is a non-null, properly aligned pointer to a valid `FuzzTestFeedbackSink`.
    /// * `(*raw).ctx` is a valid context pointer.
    /// * The sink and its context remain valid for the duration of `FeedbackSink`'s usage
    ///   (guaranteed by the engine until `FreeCtx` is called on the adapter).
    pub unsafe fn from_raw(raw: *const engine_ffi::FuzzTestFeedbackSink) -> Self {
        // SAFETY: Caller guarantees `raw` is a valid pointer to `FuzzTestFeedbackSink`.
        let raw_sink = unsafe { *raw };
        Self { raw: raw_sink }
    }

    /// Emits execution coverage features to the underlying feedback sink.
    pub fn emit_coverage_features(&mut self, features: &[u64]) {
        let emit =
            self.raw.emit_coverage_features.expect("EmitCoverageFeatures is required by ABI");
        let view = engine_ffi::FuzzTestUint64sView::from_slice(features);
        // SAFETY: The presence of `self` guarantees `from_raw` was called with a valid context
        // pointer (`self.raw.ctx`) that remains live for the duration of this call.
        unsafe {
            emit(self.raw.ctx, &view);
        }
    }

    /// Emits SanitizerCoverage features.
    pub fn emit_sancov_features(&mut self) {
        // SAFETY: the sink pointer is guaranteed to be valid by the framework.
        unsafe { SanCovRuntimeEmitFeatures(&self.raw) };
    }
}

/// Information describing a coverage feature domain.
///
/// This is a high-level  wrapper for [`engine_ffi::FuzzTestCoverageDomain`],
/// which is the Rust representation of the C struct `FuzzTestCoverageDomain`
/// defined in `engine_abi.h` (the source of truth for the ABI).
///
/// Unlike the FFI representation which uses [`engine_ffi::FuzzTestBytesView`],
/// this type uses Rust slices (`&[u8]`) for safety and convenience. It can be
/// converted to the FFI representation using `From`/`Into`.
///
/// A coverage domain represents a logically independent feature namespace registered in
/// `CoverageDomainRegistry`. FuzzTest packs 64-bit coverage features into three parts:
/// * Bits 63..59 (5 bits): 5-bit domain ID (`domain_id`, up to 32 domains).
/// * Bits 58..32 (27 bits): Feature ID within the domain (`feature_id_bit_size` <= 27).
/// * Bits 31..0 (32 bits): Feature counter value (`counter_bit_size` <= 32).
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct CoverageDomain<'a> {
    /// 5-bit unique domain identifier (must be < 32).
    pub domain_id: u8,
    /// Human-readable name of the domain for logging and debugging.
    pub name: &'a str,
    /// Number of bits used for feature IDs in this domain (must be <= 27).
    pub feature_id_bit_size: u8,
    /// Number of bits used for feature counter values in this domain (must be <= 32).
    pub counter_bit_size: u8,
}

impl<'a> From<CoverageDomain<'a>> for engine_ffi::FuzzTestCoverageDomain {
    fn from(domain: CoverageDomain<'a>) -> Self {
        Self {
            domain_id: domain.domain_id,
            name: engine_ffi::FuzzTestBytesView::from_bytes(domain.name.as_bytes()),
            feature_id_bit_size: domain.feature_id_bit_size,
            counter_bit_size: domain.counter_bit_size,
        }
    }
}

pub struct CoverageDomainRegistry {
    raw: engine_ffi::FuzzTestCoverageDomainRegistry,
}

impl CoverageDomainRegistry {
    /// Creates a safe wrapper from a pointer to `FuzzTestCoverageDomainRegistry`.
    ///
    /// # Safety
    ///
    /// The caller must ensure that:
    /// * `raw` is a non-null, properly aligned pointer to a valid `FuzzTestCoverageDomainRegistry`.
    /// * `(*raw).ctx` is a valid context pointer.
    /// * The registry and its context remain valid for the duration of `CoverageDomainRegistry`'s usage
    ///   (guaranteed by the engine until `FreeCtx` is called on the adapter).
    pub unsafe fn from_raw(raw: *const engine_ffi::FuzzTestCoverageDomainRegistry) -> Self {
        // SAFETY: Caller guarantees `raw` is a valid pointer to `FuzzTestCoverageDomainRegistry`.
        let raw_registry = unsafe { *raw };
        Self { raw: raw_registry }
    }

    /// Sets up SanitizerCoverage domains.
    pub fn set_up_sancov_domains(&self) {
        // SAFETY: The registry pointer is guaranteed to be valid by the framework.
        unsafe { SanCovRuntimeSetUpCoverageDomains(&self.raw) };
    }
}
