use core::fmt::Debug;
use std::io;
use ciphersuite::Ciphersuite;
use serai_client::primitives::{ExternalBalance, ExternalNetworkId};
use crate::{networks::Network, Db, Payment, Plan};
pub(crate) mod utxo;
pub(crate) mod smart_contract;
pub trait SchedulerAddendum: Send + Clone + PartialEq + Debug {
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self>;
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()>;
}
impl SchedulerAddendum for () {
fn read<R: io::Read>(_: &mut R) -> io::Result<Self> {
Ok(())
}
fn write<W: io::Write>(&self, _: &mut W) -> io::Result<()> {
Ok(())
}
}
pub trait Scheduler<N: Network>: Sized + Clone + PartialEq + Debug {
type Addendum: SchedulerAddendum;
fn empty(&self) -> bool;
fn new<D: Db>(
txn: &mut D::Transaction<'_>,
key: <N::Curve as Ciphersuite>::G,
network: ExternalNetworkId,
) -> Self;
fn from_db<D: Db>(
db: &D,
key: <N::Curve as Ciphersuite>::G,
network: ExternalNetworkId,
) -> io::Result<Self>;
fn can_use_branch(&self, balance: ExternalBalance) -> bool;
fn schedule<D: Db>(
&mut self,
txn: &mut D::Transaction<'_>,
utxos: Vec<N::Output>,
payments: Vec<Payment<N>>,
key_for_any_change: <N::Curve as Ciphersuite>::G,
force_spend: bool,
) -> Vec<Plan<N>>;
fn consume_payments<D: Db>(&mut self, txn: &mut D::Transaction<'_>) -> Vec<Payment<N>>;
fn created_output<D: Db>(
&mut self,
txn: &mut D::Transaction<'_>,
expected: u64,
actual: Option<u64>,
);
fn refund_plan<D: Db>(
&mut self,
txn: &mut D::Transaction<'_>,
output: N::Output,
refund_to: N::Address,
) -> Plan<N>;
fn shim_forward_plan(output: N::Output, to: <N::Curve as Ciphersuite>::G) -> Option<Plan<N>>;
fn forward_plan<D: Db>(
&mut self,
txn: &mut D::Transaction<'_>,
output: N::Output,
to: <N::Curve as Ciphersuite>::G,
) -> Option<Plan<N>>;
}