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

use thiserror::Error;

#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct MigrationReport {
    pub batch: Option<u64>,
    pub applied: Vec<u64>,
    pub rolled_back: Vec<u64>,
}

#[derive(Debug, Error)]
pub enum MigrationError {
    #[error("{0}")]
    Quex(
        #[from]
        #[source]
        quex::Error,
    ),
    #[error("unsupported database url `{0}`")]
    UnsupportedDatabaseUrl(String),
    #[error("database backend `{0}` is not enabled")]
    BackendNotEnabled(&'static str),
    #[error("duplicate migration version `{0}` is registered")]
    DuplicateVersion(u64),
    #[error("missing migration registration for applied version `{0}`")]
    MissingMigration(u64),
    #[error("failed to read migration directory `{path}`")]
    MigrationDirectory {
        path: PathBuf,
        #[source]
        source: io::Error,
    },
    #[error("migration io error: {0}")]
    Io(#[from] io::Error),
    #[error("invalid migration filename `{0}`")]
    InvalidMigrationFilename(PathBuf),
    #[error("invalid migration file `{path}`: {message}")]
    InvalidMigrationFile { path: PathBuf, message: String },
    #[error("unsupported column type `{0}`")]
    UnsupportedColumnType(String),
    #[error("applied migration `{id}` checksum mismatch")]
    ChecksumMismatch { id: u64 },
    #[error("migration `{id}` is in failed state")]
    FailedMigration { id: u64 },
}

pub struct ResetReport {
    pub batches: Vec<u64>,
    pub rolled_back: Vec<u64>,
}
