#![allow(clippy::result_large_err)]

use std::path::PathBuf;

use ambient_ci::runlog::RunLogError;
use radicle::prelude::RepoId;

pub mod ambient;
pub mod config;
pub mod runlog;

#[derive(Debug, thiserror::Error)]
pub enum AdapterError {
    #[error("failed to write message reporting run has been triggered")]
    Triggered(#[source] radicle_ci_broker::msg::helper::MessageHelperError),

    #[error("failed to write response message reporting success")]
    Succeded(#[source] radicle_ci_broker::msg::helper::MessageHelperError),

    #[error("failed to write response message reporting failure")]
    Failed(#[source] radicle_ci_broker::msg::helper::MessageHelperError),

    #[error("failed to read request from stdin")]
    ReadRequest(#[source] radicle_ci_broker::msg::helper::MessageHelperError),

    #[error(transparent)]
    Config(#[from] crate::config::ConfigError),

    #[error("failed to extract commit from request message")]
    Commit(#[source] radicle_ci_broker::msg::MessageError),

    #[error("failed to create a temporary directory")]
    TempDir(#[source] std::io::Error),

    #[error("failed to load Radicle profile")]
    Profile(#[source] radicle::profile::Error),

    #[error("failed to invoke command {0}")]
    Invoke(&'static str, #[source] std::io::Error),

    #[error("failed to run command {0}")]
    Command(&'static str, #[source] std::io::Error),

    #[error("failed to serialize Ambient project list to YAML")]
    ToYaml(#[source] serde_norway::Error),

    #[error("failed to serialize Ambient configuration value as YAML")]
    AmbientConfigToYaml(#[source] serde_norway::Error),

    #[error("failed to write Ambient project list to file")]
    WriteProjects(#[source] std::io::Error),

    #[error("failed to create directory {0}")]
    CreateDirs(PathBuf, #[source] std::io::Error),

    #[error("failed to write run log to file")]
    WriteRunLog(PathBuf, #[source] std::io::Error),

    #[error("failed to read CI plan from project {0}")]
    ReadPlan(PathBuf, #[source] std::io::Error),

    #[error("failed to parse CI plan as YAML fro file {0}")]
    ParsePlan(PathBuf, #[source] serde_norway::Error),

    #[error("failed to serialize trigger message as JSON")]
    ToJson(#[source] serde_json::Error),

    #[error("failed to write temporary configuration file")]
    WriteConfig(#[source] std::io::Error),

    #[error("failed to run ambient to get its configurarion")]
    GetAmbientConfig,

    #[error(transparent)]
    AdminLog(#[from] radicle_ci_broker::msg::helper::LogError),

    #[error(transparent)]
    MessageHelper(#[from] radicle_ci_broker::msg::helper::MessageHelperError),

    #[error("failed to measure how long CI run took")]
    Elapsed(#[source] std::time::SystemTimeError),

    #[error("programming error: field {0} is not set in RunInfoBuilder")]
    Missing(&'static str),

    #[error("failed to format time stamp")]
    TimeOffset(#[source] std::time::SystemTimeError),

    #[error("failed to format time stamp")]
    Timestamp(#[source] time::error::Format),

    #[error("failed to load identity doc for repository {0}")]
    GetIdDoc(RepoId, #[source] radicle::storage::RepositoryError),

    #[error("failed to get project information from repository identity doc")]
    GetProject(#[source] radicle::identity::doc::PayloadError),

    #[error("failed to create temporary directory on remote host {0}")]
    Mkdtemp(String, #[source] clingwrap::runner::CommandError),

    #[error("failed to parse JSON run log from Ambient")]
    RunLog(#[source] RunLogError),
}
