// This file is autogenerated with https://github.com/acheroncrypto/native-to-anchor

use anchor_lang::prelude::*;

declare_id!("11111111111111111111111111111111");

#[program]
pub mod spl_binary_oracle_pair {
    use super::*;

    pub fn init_pool(
        ctx: Context<InitPool>,
        mint_end_slot: u64,
        decide_end_slot: u64,
        bump_seed: u8,
    ) -> Result<()> {
        Ok(())
    }

    pub fn deposit(ctx: Context<Deposit>, arg: u64) -> Result<()> {
        Ok(())
    }

    pub fn withdraw(ctx: Context<Withdraw>, arg: u64) -> Result<()> {
        Ok(())
    }

    pub fn decide(ctx: Context<Decide>, arg: bool) -> Result<()> {
        Ok(())
    }
}

#[derive(Accounts)]
pub struct InitPool<'info> {
    #[account(mut)]
    pool: AccountInfo<'info>,
    authority: AccountInfo<'info>,
    decider: AccountInfo<'info>,
    deposit_token_mint: AccountInfo<'info>,
    #[account(mut)]
    deposit_account: AccountInfo<'info>,
    #[account(mut)]
    token_pass_mint: AccountInfo<'info>,
    #[account(mut)]
    token_fail_mint: AccountInfo<'info>,
    rent: Sysvar<'info, Rent>,
    token_program: Program<'info, Token>,
}

#[derive(Accounts)]
pub struct Deposit<'info> {
    pool: AccountInfo<'info>,
    authority: AccountInfo<'info>,
    user_transfer_authority: Signer<'info>,
    #[account(mut)]
    user_token_account: AccountInfo<'info>,
    #[account(mut)]
    pool_deposit_token_account: AccountInfo<'info>,
    #[account(mut)]
    token_pass_mint: AccountInfo<'info>,
    #[account(mut)]
    token_fail_mint: AccountInfo<'info>,
    #[account(mut)]
    token_pass_destination_account: AccountInfo<'info>,
    #[account(mut)]
    token_fail_destination_account: AccountInfo<'info>,
    clock: Sysvar<'info, Clock>,
    token_program: Program<'info, Token>,
}

#[derive(Accounts)]
pub struct Withdraw<'info> {
    pool: AccountInfo<'info>,
    authority: AccountInfo<'info>,
    user_transfer_authority: Signer<'info>,
    #[account(mut)]
    pool_deposit_token_account: AccountInfo<'info>,
    #[account(mut)]
    token_pass_user_account: AccountInfo<'info>,
    #[account(mut)]
    token_fail_user_account: AccountInfo<'info>,
    #[account(mut)]
    token_pass_mint: AccountInfo<'info>,
    #[account(mut)]
    token_fail_mint: AccountInfo<'info>,
    #[account(mut)]
    user_token_destination_account: AccountInfo<'info>,
    clock: Sysvar<'info, Clock>,
    token_program: Program<'info, Token>,
}

#[derive(Accounts)]
pub struct Decide<'info> {
    #[account(mut)]
    pool: AccountInfo<'info>,
    decider: Signer<'info>,
    clock: Sysvar<'info, Clock>,
}

#[account]
pub struct Pool {
    /// Initialized state.
    pub version: u8,

    /// Nonce used in program address.
    pub bump_seed: u8,

    /// Program ID of the tokens
    pub token_program_id: Pubkey,

    /// Account to deposit into
    pub deposit_account: Pubkey,

    /// Mint information for token Pass
    pub token_pass_mint: Pubkey,

    /// Mint information for token Fail
    pub token_fail_mint: Pubkey,

    /// decider key
    pub decider: Pubkey,

    /// mint end slot
    pub mint_end_slot: u64,

    /// decide end slot
    pub decide_end_slot: u64,

    /// decision status
    pub decision: Decision,
}

#[derive(AnchorSerialize, AnchorDeserialize)]
pub enum Decision {
    /// Decision was not made
    Undecided,
    /// Decision set at Pass
    Pass,
    /// Decision set at Fail
    Fail,
}

#[error_code]
pub enum PoolError {
    /// Pool account already in use
    #[msg("Pool account already in use")]
    AlreadyInUse,
    /// Deposit account already in use
    #[msg("Deposit account already in use")]
    DepositAccountInUse,
    /// Token mint account already in use
    #[msg("Token account already in use")]
    TokenMintInUse,
    /// Invalid seed or bump_seed was provided
    #[msg("Failed to generate program account because of invalid data")]
    InvalidAuthorityData,
    /// Invalid authority account provided
    #[msg("Invalid authority account provided")]
    InvalidAuthorityAccount,
    /// Lamport balance below rent-exempt threshold.
    #[msg("Lamport balance below rent-exempt threshold")]
    NotRentExempt,
    /// Expected an SPL Token mint
    #[msg("Input token mint account is not valid")]
    InvalidTokenMint,
    /// Amount should be more than zero
    #[msg("Amount should be more than zero")]
    InvalidAmount,
    /// Wrong decider account
    #[msg("Wrong decider account was sent")]
    WrongDeciderAccount,
    /// Signature missing in transaction
    #[msg("Signature missing in transaction")]
    SignatureMissing,
    /// Decision was already made for this pool
    #[msg("Decision was already made for this pool")]
    DecisionAlreadyMade,
    /// Decision can't be made in current slot
    #[msg("Decision can't be made in current slot")]
    InvalidSlotForDecision,
    /// Deposit can't be made in current slot
    #[msg("Deposit can't be made in current slot")]
    InvalidSlotForDeposit,
    /// No decision has been made yet
    #[msg("No decision has been made yet")]
    NoDecisionMadeYet,
}
