mod actions;
mod constants;
mod runner;
mod user_config;
mod utils;
pub use actions::{Action, ActionSteps, Actions};
pub use octocrate::{GithubWebhookPullRequestEvent, GithubWebhookPushEvent};
pub use runner::{
  get_workflow_event_payload,
  should_skip_workflow,
  CreateWorkflowOptions,
  GithubAuthorization,
  GlobalSecret,
  GlobalVolume,
  Job,
  OrganizationSecret,
  OrganizationVolume,
  Plugin,
  PluginManager,
  RepositorySecret,
  RepositoryVolume,
  Runner,
  RunnerBuilder,
  Secret,
  Step,
  StepSecret,
  StepVolume,
  Volume,
  Workflow,
  WorkflowRefType,
  WorkflowRunOptions,
  WorkflowRunner,
};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub use user_config::{
  EnvironmentVariable, UserActionStep, UserCommandStep, UserJob, UserStep, UserWorkflow,
  WorkflowLabelEvent, WorkflowPullRequestEvent, WorkflowPushEvent, WorkflowTriggerEvents,
};
pub type Id = String;
pub type StepNumber = u64;
pub type JobId = Id;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct WorkflowAPIEvent {
  pub repo_owner: String,
  pub repo_name: String,
  pub pr_number: Option<u64>,
  pub sha: String,
  pub ref_name: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
pub enum WorkflowEvent {
  Push(GithubWebhookPushEvent),
  PullRequest(GithubWebhookPullRequestEvent),
  API(WorkflowAPIEvent),
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum WorkflowLogType {
  Error,
  Log,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum WorkflowState {
  Pending,
  Queued,
  InProgress,
  Succeeded,
  Failed,
  Cancelled,
  Skipped,
}
#[derive(Debug, Clone)]
pub struct StepLog {
  pub log_type: WorkflowLogType,
  pub message: String,
  pub time: chrono::DateTime<chrono::Utc>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum WorkflowMessage {
  Log {
    workflow_run_id: Id,
    job_id: String,
    number: u64,
    log_type: WorkflowLogType,
    message: String,
    time: chrono::DateTime<chrono::Utc>,
  },
  WorkflowStateUpdated {
    id: Id,
    state: WorkflowState,
  },
  JobStateUpdated {
    workflow_run_id: Id,
    job_id: String,
    state: WorkflowState,
  },
  StepStateUpdated {
    workflow_run_id: Id,
    job_id: String,
    number: u64,
    state: WorkflowState,
  },
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StepRunResult {
  pub exit_code: Option<i32>,
  pub state: WorkflowState,
  pub started_at: Option<chrono::DateTime<chrono::Utc>>,
  pub ended_at: Option<chrono::DateTime<chrono::Utc>>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct JobRunResult {
  pub state: WorkflowState,
  pub started_at: Option<chrono::DateTime<chrono::Utc>>,
  pub ended_at: Option<chrono::DateTime<chrono::Utc>>,
  pub steps: Vec<StepRunResult>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct WorkflowRunResult {
  pub state: WorkflowState,
  pub started_at: Option<chrono::DateTime<chrono::Utc>>,
  pub ended_at: Option<chrono::DateTime<chrono::Utc>>,
  pub jobs: HashMap<String, JobRunResult>,
}
impl ToString for WorkflowRefType {
  fn to_string(&self) -> String {
    match self {
      WorkflowRefType::Branch => "branch",
      WorkflowRefType::Tag => "tag",
    }
    .to_string()
  }
}
impl From<String> for WorkflowRefType {
  fn from(event: String) -> Self {
    match event.as_str() {
      "branch" => WorkflowRefType::Branch,
      "tag" => WorkflowRefType::Tag,
      _ => WorkflowRefType::Branch,
    }
  }
}
impl ToString for WorkflowState {
  fn to_string(&self) -> String {
    match self {
      WorkflowState::Pending => "pending",
      WorkflowState::Queued => "queued",
      WorkflowState::InProgress => "in_progress",
      WorkflowState::Succeeded => "succeeded",
      WorkflowState::Failed => "failed",
      WorkflowState::Cancelled => "cancelled",
      WorkflowState::Skipped => "skipped",
    }
    .to_string()
  }
}
impl From<String> for WorkflowState {
  fn from(event: String) -> Self {
    match event.as_str() {
      "pending" => WorkflowState::Pending,
      "queued" => WorkflowState::Queued,
      "in_progress" => WorkflowState::InProgress,
      "succeeded" => WorkflowState::Succeeded,
      "failed" => WorkflowState::Failed,
      "cancelled" => WorkflowState::Cancelled,
      "skipped" => WorkflowState::Skipped,
      _ => WorkflowState::Pending,
    }
  }
}
impl WorkflowState {
  pub fn is_completed(&self) -> bool {
    match self {
      WorkflowState::Succeeded => true,
      WorkflowState::Failed => true,
      WorkflowState::Cancelled => true,
      WorkflowState::Skipped => true,
      _ => false,
    }
  }
}