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

use serde::{Deserialize, Serialize};

use crate::logfile::LogError;

/// How to run CI for this repository.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[allow(dead_code)]
pub struct RunSpec {
    /// The shell script snippet to run. It will be run with `bash`
    /// and with `set -xeuo pipefail`.
    pub shell: String,
}

impl RunSpec {
    /// Read run specification from a file.
    pub fn from_file(filename: &Path) -> Result<Self, RunSpecError> {
        let file = std::fs::File::open(filename)
            .map_err(|e| RunSpecError::ReadRunSpec(filename.into(), e))?;
        let runspec: RunSpec = serde_norway::from_reader(&file)
            .map_err(|e| RunSpecError::ParseRunSpec(filename.into(), e))?;
        Ok(runspec)
    }
}

#[derive(Debug, thiserror::Error)]
pub enum RunSpecError {
    #[error("failed to read run specification file {0}")]
    ReadRunSpec(PathBuf, #[source] std::io::Error),

    #[error("failed to parse run spec as YAML: {0}")]
    ParseRunSpec(PathBuf, #[source] serde_norway::Error),

    #[error(transparent)]
    Log(#[from] LogError),
}
