use ore_mint_api::consts::ONE_ORE;
use serde::{Deserialize, Serialize};
use steel::*;
use crate::state::{automation_pda, OreAccountV4};
use super::OreAccountV1;
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
pub struct AutomationV1 {
pub amount: u64,
pub authority: Pubkey,
pub balance: u64,
pub executor: Pubkey,
pub fee: u64,
pub strategy: u64,
pub mask: u64,
pub reload: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
pub struct AutomationV4 {
pub amount: u64,
pub authority: Pubkey,
pub balance: u64,
pub executor: Pubkey,
pub fee: u64,
pub strategy: u64,
pub mask: u64,
pub reload: u64,
pub total_sol_spent: u64,
pub total_ore_earned: u64,
pub conditions: AutomationConditions,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
pub struct AutomationConditions {
pub max_production_cost: u64,
pub min_motherlode: u64,
pub max_motherlode: u64,
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, IntoPrimitive, TryFromPrimitive)]
pub enum AutomationStrategy {
Random = 0,
Preferred = 1,
Discretionary = 2,
}
impl AutomationStrategy {
pub fn from_u64(value: u64) -> Self {
Self::try_from(value as u8).unwrap()
}
}
impl Default for AutomationConditions {
fn default() -> Self {
Self {
max_production_cost: u64::MAX,
min_motherlode: 0,
max_motherlode: u64::MAX,
}
}
}
impl AutomationV4 {
pub fn pda(&self) -> (Pubkey, u8) {
automation_pda(self.authority)
}
pub fn production_cost(&self) -> u64 {
if self.total_ore_earned == 0 {
return 0;
}
((self.total_sol_spent as u128) * (ONE_ORE as u128) / (self.total_ore_earned as u128))
as u64
}
}
account!(OreAccountV1, AutomationV1);
account!(OreAccountV4, AutomationV4);
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
pub enum Automation {
V1(AutomationV1),
V4(AutomationV4),
}
impl Automation {
pub fn amount(&self) -> u64 {
match self {
Automation::V1(a) => a.amount,
Automation::V4(a) => a.amount,
}
}
pub fn authority(&self) -> Pubkey {
match self {
Automation::V1(a) => a.authority,
Automation::V4(a) => a.authority,
}
}
pub fn balance(&self) -> u64 {
match self {
Automation::V1(a) => a.balance,
Automation::V4(a) => a.balance,
}
}
pub fn executor(&self) -> Pubkey {
match self {
Automation::V1(a) => a.executor,
Automation::V4(a) => a.executor,
}
}
pub fn fee(&self) -> u64 {
match self {
Automation::V1(a) => a.fee,
Automation::V4(a) => a.fee,
}
}
pub fn strategy(&self) -> u64 {
match self {
Automation::V1(a) => a.strategy,
Automation::V4(a) => a.strategy,
}
}
pub fn mask(&self) -> u64 {
match self {
Automation::V1(a) => a.mask,
Automation::V4(a) => a.mask,
}
}
pub fn reload(&self) -> u64 {
match self {
Automation::V1(a) => a.reload,
Automation::V4(a) => a.reload,
}
}
}