#[cfg(test)]
mod session_tests {

    use serial_test::serial;
    use std::thread::sleep;
    use std::time::Duration;

    use anyhow::Result;

    use meridian::context::{get_base_context_dir, ContextContent, ContextSession};

    fn cleanup_test_sessions() -> Result<()> {
        let base_dir = get_base_context_dir()?;
        if base_dir.exists() {
            std::fs::remove_dir_all(&base_dir)?;
        }
        Ok(())
    }

    #[test]
    #[serial]
    fn test_session_creation_and_storage() -> Result<()> {
        cleanup_test_sessions()?;

        let session = ContextSession::new()?;

        assert!(session.get_session_dir().exists());
        assert!(get_base_context_dir()?.exists());

        cleanup_test_sessions()?;
        Ok(())
    }

    #[test]
    #[serial]
    fn test_session_listing() -> Result<()> {
        cleanup_test_sessions()?;

        // Create multiple sessions with small delays
        let mut sessions = Vec::new();
        for _ in 0..3 {
            let session = ContextSession::new()?;
            sessions.push(session);
            sleep(Duration::from_millis(1100));
        }

        let listed_sessions = ContextSession::list_sessions()?;
        assert_eq!(listed_sessions.len(), 3);

        // Verify sessions are ordered newest to oldest
        for i in 1..listed_sessions.len() {
            assert!(listed_sessions[i - 1].1 > listed_sessions[i].1);
        }

        cleanup_test_sessions()?;
        Ok(())
    }

    #[test]
    #[serial]
    fn test_save_and_resume_session() {
        cleanup_test_sessions().unwrap();

        // Create and populate a session
        let mut session = ContextSession::new().unwrap();

        session.add_text_to_context("test", "test content");
        session.add_text_to_context("test.txt", "file content");

        // Save the session
        session.save_context().unwrap();

        // Resume the session
        let resumed_session = ContextSession::resume().unwrap();

        // Verify resumed context matches original
        assert_eq!(
            resumed_session.get_context().get_items().len(),
            session.get_context().get_items().len()
        );

        // Verify content of items
        if let ContextContent::Text {
            identifier,
            content,
        } = &resumed_session
            .get_context()
            .get_item_by_index(0)
            .unwrap()
            .get_content()
            .unwrap()
        {
            assert_eq!(content, "test content");
        } else {
            panic!("Wrong content type");
        }

        if let ContextContent::File { path, content } = &resumed_session
            .get_context()
            .get_item_by_index(1)
            .unwrap()
            .get_content()
            .unwrap()
        {
            assert_eq!(path, "test.txt");
            assert_eq!(content, "file content");
        } else {
            panic!("Wrong content type");
        }

        cleanup_test_sessions().unwrap();
    }

    #[test]
    #[serial]
    fn test_session_destruction() -> Result<()> {
        cleanup_test_sessions()?;

        let mut session = ContextSession::new()?;

        let session_dir = session.get_session_dir().clone();
        assert!(session_dir.exists());

        session.destroy_context_session_storage()?;
        assert!(!session_dir.exists());

        cleanup_test_sessions()?;
        Ok(())
    }

    #[test]
    #[serial]
    fn test_resume_latest_session() -> Result<()> {
        cleanup_test_sessions()?;

        // Create multiple sessions with different content
        let mut sessions = Vec::new();
        for i in 0..3 {
            let mut session = ContextSession::new()?;
            session.add_text_to_context("test", &format!("content {}", i));
            session.save_context()?;
            sessions.push(session);
            sleep(Duration::from_millis(100));
        }

        // Get the last session directory
        let last_session_dir = sessions.last().unwrap().get_session_dir().clone();

        // Resume latest session
        let resumed_session = ContextSession::resume()?;

        // Verify it's the latest session
        if let ContextContent::Text {
            identifier,
            content,
        } = &resumed_session
            .get_context()
            .get_item_by_index(0)
            .unwrap()
            .get_content()?
        {
            assert_eq!(content, "content 2");
        } else {
            panic!("Wrong content type");
        }

        cleanup_test_sessions()?;
        Ok(())
    }
}
