//! Compatibility facade over the native capability-backed texture downloader.

use crate::{Error, GridClient};
use libremetaverse_types::UUID;
use std::sync::atomic::{AtomicBool, Ordering};

pub struct TexturePipeline {
    client: GridClient,
    running: AtomicBool,
}

impl TexturePipeline {
    pub fn new(client: GridClient) -> Result<Self, Error> {
        // Resolve the manager eagerly so construction fails for a disposed or
        // incompletely initialized client instead of at the first abort.
        client.native_assets()?;
        Ok(Self {
            client,
            running: AtomicBool::new(false),
        })
    }

    pub fn abort_texture_request(&self, texture_id: UUID) -> Result<(), Error> {
        if texture_id == UUID::zero() {
            return Ok(());
        }
        self.client
            .native_assets()?
            .request_image_cancel(texture_id)
    }

    pub fn shutdown(&self) -> Result<(), Error> {
        if self.running.swap(false, Ordering::AcqRel) {
            self.client.native_assets()?.native_cancel_image_requests();
        }
        Ok(())
    }

    pub fn startup(&self) -> Result<(), Error> {
        self.client.native_assets()?;
        if self.client.settings_ref().texture_pipeline.enabled {
            self.running.store(true, Ordering::Release);
        }
        Ok(())
    }

    #[must_use]
    pub fn transfer_count(&self) -> i32 {
        self.client
            .native_assets()
            .map_or(0, |assets| assets.native_image_transfer_count())
    }
}

impl Drop for TexturePipeline {
    fn drop(&mut self) {
        let _ = self.shutdown();
    }
}
