use crate::candidate_selection::hashing::HashInstructions;
use crate::file_descriptor::FileDescriptor;
use anyhow::Result;
use std::fs::File;
use std::path::{Path, PathBuf};

#[derive(Debug)]
pub enum AnalysisMessage {
    Update(AnalysisStatistics),
    Finished(AnalysisStatistics),
}

#[derive(Debug)]
pub struct AnalysisStatistics {
    pub files_found: u64,
    pub duplicates_found: u64,
    pub total_bytes_encountered: u64,
    pub total_bytes_read: u64,
    pub total_bytes_duplicated: u64,
}

pub enum WorkerMessage {
    HashComputed(FileWithDescriptor, HashComputedResult),
    NotHashable(FileWithDescriptor),
}

pub enum CoordinatorMessage {
    HashCommand(FileWithDescriptor, HashInstructions),
}

pub struct HashComputedResult {
    pub hash: u64,
    pub instructions: HashInstructions,
}

pub enum FileWalkerMessage {
    FileFound(PathBuf),
    WalkCompleted,
}

#[derive(Debug)]
pub struct FileWithDescriptor {
    pub file: File,
    pub file_descriptor: FileDescriptor,
}

impl FileWithDescriptor {
    pub fn from_path(path: &Path) -> Result<FileWithDescriptor> {
        trace!("File::open");
        let file = File::open(path)?;
        trace!("FileDescriptor::from_file");
        let file_descriptor = FileDescriptor::from_file(&file)?;
        trace!("Ok(FileWithHandle)");

        Ok(FileWithDescriptor {
            file,
            file_descriptor,
        })
    }
}
