use compliance_core::models::TrackerIssue;
use compliance_core::traits::issue_tracker::IssueTracker;

use crate::trackers;

/// Enum dispatch for issue trackers (async traits aren't dyn-compatible).
pub(crate) enum TrackerDispatch {
    GitHub(trackers::github::GitHubTracker),
    GitLab(trackers::gitlab::GitLabTracker),
    Gitea(trackers::gitea::GiteaTracker),
    Jira(trackers::jira::JiraTracker),
}

impl TrackerDispatch {
    pub(crate) fn name(&self) -> &str {
        match self {
            Self::GitHub(t) => t.name(),
            Self::GitLab(t) => t.name(),
            Self::Gitea(t) => t.name(),
            Self::Jira(t) => t.name(),
        }
    }

    pub(crate) async fn create_issue(
        &self,
        owner: &str,
        repo: &str,
        title: &str,
        body: &str,
        labels: &[String],
    ) -> Result<TrackerIssue, compliance_core::error::CoreError> {
        match self {
            Self::GitHub(t) => t.create_issue(owner, repo, title, body, labels).await,
            Self::GitLab(t) => t.create_issue(owner, repo, title, body, labels).await,
            Self::Gitea(t) => t.create_issue(owner, repo, title, body, labels).await,
            Self::Jira(t) => t.create_issue(owner, repo, title, body, labels).await,
        }
    }

    pub(crate) async fn find_existing_issue(
        &self,
        owner: &str,
        repo: &str,
        fingerprint: &str,
    ) -> Result<Option<TrackerIssue>, compliance_core::error::CoreError> {
        match self {
            Self::GitHub(t) => t.find_existing_issue(owner, repo, fingerprint).await,
            Self::GitLab(t) => t.find_existing_issue(owner, repo, fingerprint).await,
            Self::Gitea(t) => t.find_existing_issue(owner, repo, fingerprint).await,
            Self::Jira(t) => t.find_existing_issue(owner, repo, fingerprint).await,
        }
    }

    pub(crate) async fn create_pr_review(
        &self,
        owner: &str,
        repo: &str,
        pr_number: u64,
        body: &str,
        comments: Vec<compliance_core::traits::issue_tracker::ReviewComment>,
    ) -> Result<(), compliance_core::error::CoreError> {
        match self {
            Self::GitHub(t) => {
                t.create_pr_review(owner, repo, pr_number, body, comments)
                    .await
            }
            Self::GitLab(t) => {
                t.create_pr_review(owner, repo, pr_number, body, comments)
                    .await
            }
            Self::Gitea(t) => {
                t.create_pr_review(owner, repo, pr_number, body, comments)
                    .await
            }
            Self::Jira(t) => {
                t.create_pr_review(owner, repo, pr_number, body, comments)
                    .await
            }
        }
    }
}
