// DO NOT EDIT — generated by `harn connector-schema-codegen`.
//
// Source of truth: crates/harn-stdlib/src/stdlib/stdlib_event_schemas.harn
// Regenerate with: make gen-connector-schemas
// Verify (CI):     make check-connector-schemas
//
// These structs are generated from canonical Harn `type` declarations so a
// connector's normalized-event JSON matches the Rust struct by construction.
// This file currently coexists with the hand-written `GitHubEventPayload`
// family in `payloads.rs`; switching the trigger boundary to produce these
// typed payloads is a separate follow-up.

use std::collections::BTreeMap;

use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value as JsonValue;

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitForgeRepositoryRef {
    pub provider: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub full_name: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub web_url: Option<String>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitForgePullRequestRef {
    pub number: i64,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub title: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub author: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub web_url: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub head_ref: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub head_sha: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub base_ref: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub base_sha: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub state: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub draft: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub merged: Option<bool>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitForgeWritebackTarget {
    pub provider: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub repository_full_name: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub repository_id: Option<String>,
    pub pull_request_number: i64,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub web_url: Option<String>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitForgePullRequestEvent {
    pub topic: String,
    pub event: String,
    pub kind: String,
    pub provider: String,
    pub lifecycle: String,
    pub repository: GitForgeRepositoryRef,
    pub pull_request: GitForgePullRequestRef,
    pub writeback: GitForgeWritebackTarget,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub delivery_id: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub signature_status: Option<JsonValue>,
    #[serde(default)]
    pub provider_metadata: BTreeMap<String, JsonValue>,
    pub raw_payload: JsonValue,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubEventCommon {
    pub event: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub action: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub delivery_id: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub installation_id: Option<i64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub topic: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub repository: Option<JsonValue>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub repo: Option<JsonValue>,
    pub raw: JsonValue,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubIssuesEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    pub issue: JsonValue,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubPullRequestEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    pub pull_request: JsonValue,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubIssueCommentEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    pub issue: JsonValue,
    pub comment: JsonValue,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubPullRequestReviewEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    pub pull_request: JsonValue,
    pub review: JsonValue,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubPushEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    #[serde(default)]
    pub commits: Vec<JsonValue>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub distinct_size: Option<i64>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubWorkflowRunEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    pub workflow_run: JsonValue,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubDeploymentStatusEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    pub deployment_status: JsonValue,
    pub deployment: JsonValue,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubCheckRunEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    pub check_run: JsonValue,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubCheckSuiteEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    pub check_suite: JsonValue,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub check_suite_id: Option<i64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub pull_request_number: Option<i64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub head_sha: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub head_ref: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub base_ref: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub status: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub conclusion: Option<String>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubStatusEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub commit_status: Option<JsonValue>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub status_id: Option<i64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub head_sha: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub head_ref: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub base_ref: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub state: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub context: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub target_url: Option<String>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubMergeGroupEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    pub merge_group: JsonValue,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub merge_group_id: Option<JsonValue>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub head_sha: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub head_ref: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub base_sha: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub base_ref: Option<String>,
    #[serde(default)]
    pub pull_requests: Vec<JsonValue>,
    #[serde(default)]
    pub pull_request_numbers: Vec<i64>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubInstallationEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub installation: Option<JsonValue>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub account: Option<JsonValue>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub installation_state: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub suspended: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub revoked: Option<bool>,
    #[serde(default)]
    pub repositories: Vec<JsonValue>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GitHubInstallationRepositoriesEventPayload {
    #[serde(flatten)]
    pub common: GitHubEventCommon,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub installation: Option<JsonValue>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub account: Option<JsonValue>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub installation_state: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub suspended: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub revoked: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub repository_selection: Option<String>,
    #[serde(default)]
    pub repositories_added: Vec<JsonValue>,
    #[serde(default)]
    pub repositories_removed: Vec<JsonValue>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
#[serde(untagged)]
pub enum GitHubEventPayload {
    Issues(GitHubIssuesEventPayload),
    PullRequest(GitHubPullRequestEventPayload),
    IssueComment(GitHubIssueCommentEventPayload),
    PullRequestReview(GitHubPullRequestReviewEventPayload),
    Push(GitHubPushEventPayload),
    WorkflowRun(GitHubWorkflowRunEventPayload),
    DeploymentStatus(GitHubDeploymentStatusEventPayload),
    CheckRun(GitHubCheckRunEventPayload),
    CheckSuite(GitHubCheckSuiteEventPayload),
    Status(GitHubStatusEventPayload),
    MergeGroup(GitHubMergeGroupEventPayload),
    Installation(GitHubInstallationEventPayload),
    InstallationRepositories(GitHubInstallationRepositoriesEventPayload),
    Other(GitHubEventCommon),
}

impl<'de> Deserialize<'de> for GitHubEventPayload {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let value = JsonValue::deserialize(deserializer)?;
        let kind = value
            .get("event")
            .and_then(JsonValue::as_str)
            .unwrap_or("")
            .to_string();
        let payload = match kind.as_str() {
            "issues" => GitHubEventPayload::Issues(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            "pull_request" => GitHubEventPayload::PullRequest(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            "issue_comment" => GitHubEventPayload::IssueComment(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            "pull_request_review" => GitHubEventPayload::PullRequestReview(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            "push" => GitHubEventPayload::Push(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            "workflow_run" => GitHubEventPayload::WorkflowRun(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            "deployment_status" => GitHubEventPayload::DeploymentStatus(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            "check_run" => GitHubEventPayload::CheckRun(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            "check_suite" => GitHubEventPayload::CheckSuite(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            "status" => GitHubEventPayload::Status(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            "merge_group" => GitHubEventPayload::MergeGroup(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            "installation" => GitHubEventPayload::Installation(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            "installation_repositories" => GitHubEventPayload::InstallationRepositories(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
            _ => GitHubEventPayload::Other(
                serde_json::from_value(value).map_err(serde::de::Error::custom)?,
            ),
        };
        Ok(payload)
    }
}
