use async_mutex::Mutex;
use event_listener::Event;
use std::collections::VecDeque;

use super::page::PageResult;

pub struct TaskRunner {
    pub queue: VecDeque<Box<dyn PageResult>>,
    pub crawler_done: bool,
}

impl TaskRunner {
    pub fn new() -> Self {
        Self {
            queue: VecDeque::new(),
            crawler_done: false,
        }
    }

    pub async fn run(tasks_mutex: &(Mutex<TaskRunner>, Event)) {
        let (task_runner_mutex, event) = (&tasks_mutex.0, &tasks_mutex.1);
        loop {
            let mut task_runner = task_runner_mutex.lock().await;
            if task_runner.crawler_done && task_runner.queue.len() == 0 {
                break;
            }

            if task_runner.queue.len() == 0 {
                let listener = event.listen();
                drop(task_runner);
                listener.await;
                continue;
            }

            let task = task_runner.queue.pop_front().unwrap();
            drop(task_runner);

            if let Err(err) = task.save_results().await {
                println!("Error processing task: {:?}", err);
            }
        }
    }
}
