// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

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) };
    }
}
