#[cfg(feature = "tracy")]
use std::time::Instant;

#[cfg(feature = "tracy")]
use crate::backends::base::TracingBackend;
#[cfg(feature = "tracy")]
use tracy_client;

#[cfg(feature = "tracy")]
use crate::profile_result::ProfileResult;

#[cfg(feature = "tracy")]
pub struct TracyProfiler {
    max_frames: Option<usize>,
    pub frame_count: usize,
    max_duration_ms: Option<u64>,
    start_time: Option<Instant>,
    _client: tracy_client::Client,
}

#[cfg(feature = "tracy")]
impl TracyProfiler {
    pub fn new() -> Self {
        Self {
            max_frames: None,
            frame_count: 0,
            max_duration_ms: None,
            start_time: None,
            _client: tracy_client::Client::start(),
        }
    }
}

#[cfg(feature = "tracy")]
impl TracingBackend for TracyProfiler {
    fn begin_session(&mut self, _name: &str, _filepath: &str) {}

    fn begin_session_limited(
        &mut self,
        _name: &str,
        _filepath: &str,
        max_frames: Option<usize>,
        max_duration_ms: Option<u64>,
    ) {
        self.max_frames = Some(max_frames.unwrap_or(usize::MAX));
        self.max_duration_ms = max_duration_ms;
        self.frame_count = 0;
        self.start_time = Some(Instant::now());
    }

    fn end_session(&mut self) -> Result<(), String> {
        Ok(())
    }

    fn new_frame(&mut self) {
        self.frame_count += 1;

        if let Some(max) = self.max_frames {
            if self.frame_count >= max {
                return;
            }
        }

        if let Some(max_ms) = self.max_duration_ms {
            if let Some(start) = self.start_time {
                if start.elapsed().as_millis() as u64 >= max_ms {
                    return;
                }
            }
        }

        tracy_client::frame_mark();
    }

    fn record_event(&mut self, _event: &ProfileResult) {}

    fn record_span(&mut self, _name: &str) {}
}
