use std::{io, path::PathBuf};

use crate::CacheId;


#[derive(Debug, thiserror::Error)]
#[error("Error during cache operation")]
pub enum CacheError {
    InputCheck(#[from] InputCheckError),
    IndexLoad(#[from] IndexLoadError),
    IndexSave(#[from] IndexSaveError),
    OutputCreation(#[from] OutputCreationError),
    OutputCheck(#[from] OutputCheckError),
}
pub type CacheResult<T> = Result<T, CacheError>;


#[derive(Debug, thiserror::Error)]
pub enum InputCheckError {
    #[error("Error while checking if input {input_id} changed")]
    ChangeIndicator { input_id: CacheId, source: cicero_core::Error }
}

#[derive(Debug, thiserror::Error)]
#[error("Error while executing provided code for creating output {output:?}")]
pub struct OutputCreationError { pub output: PathBuf, pub source: cicero_core::Error }


#[derive(Debug, thiserror::Error)]
pub enum OutputCheckError {
    #[error("Error while checking if the output {output_id} has changed since the previous execution")]
    PreviousChanged { output_id: CacheId, source: cicero_core::Error },
    #[error("Error while checking if the output {output_id} has changed after executing the provided creation code")]
    ChangedAfterCreationCode { output_id: CacheId, source: cicero_core::Error },
}

#[derive(Debug, thiserror::Error)]
pub enum IndexLoadError {
    #[error("Could not open index file, even though it exists at {file:?}")]
    ExistsButCannotOpen { file: PathBuf, source: io::Error },
}

#[derive(Debug, thiserror::Error)]
#[error("Failed to save index to file {file:?}")]
pub enum IndexSaveError {
    Serialize { file: PathBuf, source: serde_json::Error },
    Io { file: PathBuf, source: io::Error },
}
