pub mod assertions;
pub mod constants;
pub mod errors;
pub mod instructions;
pub mod state;
use {
    anchor_lang::prelude::*,
    instructions::*,
    state::{DelegateAuthority, Project, SerializableActions},
};
declare_id!("HivezrprVqHR6APKKQkkLHmUG8waZorXexEBRZWh5LRm");
fn profile_platform_gate<'info>(
    project: &Account<'info, Project>,
    signer_key: Pubkey,
    payer: AccountInfo<'info>,
    vault: AccountInfo<'info>,
    delegate_authority: &Option<Account<'info, DelegateAuthority>>,
    system_program: AccountInfo<'info>,
    instructions_sysvar: AccountInfo<'info>,
) -> Result<()> {
    if signer_key.eq(&project.driver) {
        msg!("Driver action");
        instructions::platform_gate_fn(
            SerializableActions::DriverAction,
            Some((0, Pubkey::default())),
            project,
            signer_key,
            payer,
            vault,
            delegate_authority,
            system_program,
            instructions_sysvar,
            ID,
        )
    } else {
        instructions::platform_gate_fn(
            SerializableActions::PublicLow,
            None,
            project,
            signer_key,
            payer,
            vault,
            delegate_authority,
            system_program,
            instructions_sysvar,
            ID,
        )
    }
}
#[program]
pub mod hpl_hive_control {
    use super::*;
    pub fn init_public_info(ctx: Context<InitPublicInfo>, env: String) -> Result<()> {
        assertions::assert_program_authority(
            ctx.accounts.program.to_account_info(),
            ctx.accounts.program_data.to_account_info(),
            ctx.accounts.authority.key,
        )?;
        instructions::init_public_info(ctx, env)
    }
    pub fn set_public_info(
        ctx: Context<SetPublicInfo>,
        env: String,
        args: SetPublicInfoArgs,
    ) -> Result<()> {
        assertions::assert_program_authority(
            ctx.accounts.program.to_account_info(),
            ctx.accounts.program_data.to_account_info(),
            ctx.accounts.authority.key,
        )?;
        instructions::set_public_info(ctx, env, args)
    }
    pub fn set_auth_driver(
        ctx: Context<SetAuthDriver>,
        env: String,
        args: SetAuthDriverArgs,
    ) -> Result<()> {
        assertions::assert_program_authority(
            ctx.accounts.program.to_account_info(),
            ctx.accounts.program_data.to_account_info(),
            ctx.accounts.authority.key,
        )?;
        instructions::set_auth_driver(ctx, env, args)
    }
    pub fn platform_gate(ctx: Context<PlatformGate>, args: PlatformGateArgs) -> Result<()> {
        instructions::platform_gate(ctx, args)
    }
    pub fn create_project(ctx: Context<CreateProject>, args: CreateProjectArgs) -> Result<()> {
        instructions::platform_gate_fn(
            SerializableActions::CreateProject,
            None,
            &ctx.accounts.project,
            ctx.accounts.authority.key(),
            ctx.accounts.payer.to_account_info(),
            ctx.accounts.vault.to_account_info(),
            &None,
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.instructions_sysvar.to_account_info(),
            ID,
        )?;
        instructions::create_project(ctx, args)
    }
    pub fn change_driver(ctx: Context<ChangeDriver>) -> Result<()> {
        instructions::platform_gate_fn(
            SerializableActions::ManageDelegateAuthority,
            None,
            &ctx.accounts.project,
            ctx.accounts.authority.key(),
            ctx.accounts.payer.to_account_info(),
            ctx.accounts.vault.to_account_info(),
            &ctx.accounts.delegate_authority,
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.instructions_sysvar.to_account_info(),
            ID,
        )?;
        instructions::change_driver(ctx)
    }
    pub fn add_remove_criteria(
        ctx: Context<AddRemoveCriteria>,
        args: AddRemoveCriteriaArgs,
    ) -> Result<()> {
        instructions::platform_gate_fn(
            SerializableActions::ManageCriterias,
            None,
            &ctx.accounts.project,
            ctx.accounts.authority.key(),
            ctx.accounts.payer.to_account_info(),
            ctx.accounts.vault.to_account_info(),
            &ctx.accounts.delegate_authority,
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.instructions_sysvar.to_account_info(),
            ID,
        )?;
        instructions::add_remove_criteria(ctx, args)
    }
    pub fn add_remove_service(
        ctx: Context<AddRemoveService>,
        args: AddRemoveServiceArgs,
    ) -> Result<()> {
        instructions::platform_gate_fn(
            if args.remove.unwrap_or(false) {
                SerializableActions::RemoveService
            } else {
                SerializableActions::AddService
            },
            None,
            &ctx.accounts.project,
            ctx.accounts.authority.key(),
            ctx.accounts.payer.to_account_info(),
            ctx.accounts.vault.to_account_info(),
            &ctx.accounts.delegate_authority,
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.instructions_sysvar.to_account_info(),
            ID,
        )?;
        instructions::add_remove_service(ctx, args)
    }
    pub fn add_remove_profile_data_config(
        ctx: Context<AddRemoveProfileDataConfig>,
        args: AddRemoveProfileDataConfigArgs,
    ) -> Result<()> {
        instructions::platform_gate_fn(
            SerializableActions::ManageProfiles,
            None,
            &ctx.accounts.project,
            ctx.accounts.authority.key(),
            ctx.accounts.payer.to_account_info(),
            ctx.accounts.vault.to_account_info(),
            &ctx.accounts.delegate_authority,
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.instructions_sysvar.to_account_info(),
            ID,
        )?;
        instructions::add_remove_profile_data_config(ctx, args)
    }
    pub fn clear_profile_data_config(ctx: Context<ClearProfileDataConfig>) -> Result<()> {
        instructions::platform_gate_fn(
            SerializableActions::ManageProfiles,
            None,
            &ctx.accounts.project,
            ctx.accounts.authority.key(),
            ctx.accounts.payer.to_account_info(),
            ctx.accounts.vault.to_account_info(),
            &ctx.accounts.delegate_authority,
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.instructions_sysvar.to_account_info(),
            ID,
        )?;
        instructions::clear_profile_data_config(ctx)
    }
    pub fn add_address_container_to_project(
        ctx: Context<AddAddressContainerToProject>,
        args: AddAddressContainerToProjectArgs,
    ) -> Result<()> {
        instructions::platform_gate_fn(
            SerializableActions::ManageIndexing,
            None,
            &ctx.accounts.project,
            ctx.accounts.authority.key(),
            ctx.accounts.payer.to_account_info(),
            ctx.accounts.vault.to_account_info(),
            &ctx.accounts.delegate_authority,
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.instructions_sysvar.to_account_info(),
            ID,
        )?;
        instructions::add_address_container_to_project(ctx, args)
    }
    pub fn add_mint_addresses_to_address_container(
        ctx: Context<AddMintAddressesToAddressContainer>,
        args: AddMintAddressesToAddressContainerArgs,
    ) -> Result<()> {
        instructions::add_mint_addresses_to_address_container(ctx, args)
    }
    pub fn create_delegate_authority(
        ctx: Context<CreateDelegateAuthority>,
        args: CreateDelegateAuthorityArgs,
    ) -> Result<()> {
        instructions::platform_gate_fn(
            SerializableActions::ManageDelegateAuthority,
            None,
            &ctx.accounts.project,
            ctx.accounts.authority.key(),
            ctx.accounts.payer.to_account_info(),
            ctx.accounts.vault.to_account_info(),
            &None,
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.instructions_sysvar.to_account_info(),
            ID,
        )?;
        instructions::create_delegate_authority(ctx, args)
    }
    pub fn add_remove_delegation(
        ctx: Context<ModifyDelegate>,
        args: AddRemoveDelegationArgs,
    ) -> Result<()> {
        instructions::platform_gate_fn(
            SerializableActions::ManageDelegateAuthority,
            None,
            &ctx.accounts.project,
            ctx.accounts.authority.key(),
            ctx.accounts.payer.to_account_info(),
            ctx.accounts.vault.to_account_info(),
            &None,
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.instructions_sysvar.to_account_info(),
            ID,
        )?;
        instructions::add_remove_delegation(ctx, args)
    }
    pub fn initialize_user(ctx: Context<InitializeUser>, args: InitializeUserArgs) -> Result<()> {
        instructions::initialize_user(ctx, args)
    }
    pub fn close_user(ctx: Context<CloseUser>) -> Result<()> {
        instructions::close_user(ctx)
    }
    pub fn update_user(ctx: Context<UpdateUser>, env: String, args: UpdateUserArgs) -> Result<()> {
        let assert_user = assertions::assert_user(&ctx.accounts.user, ctx.accounts.authority.key());
        if assert_user.is_err() {
            assertions::assert_auth_driver(&ctx.accounts.public_info, &ctx.accounts.authority)?;
        }
        instructions::update_user(ctx, env, args)
    }
    pub fn add_wallet(ctx: Context<AddWallet>, env: String) -> Result<()> {
        let assert_user = assertions::assert_user(&ctx.accounts.user, ctx.accounts.authority.key());
        if assert_user.is_err() {
            assertions::assert_auth_driver(&ctx.accounts.public_info, &ctx.accounts.authority)?;
        }
        instructions::add_wallet(ctx, env)
    }
    pub fn delete_wallet(ctx: Context<DeleteWallet>, env: String) -> Result<()> {
        let assert_user = assertions::assert_user(&ctx.accounts.user, ctx.accounts.authority.key());
        if assert_user.is_err() {
            assertions::assert_auth_driver(&ctx.accounts.public_info, &ctx.accounts.authority)?;
        }
        instructions::delete_wallet(ctx, env)
    }
    pub fn create_profile(ctx: Context<CreateProfile>, args: CreateProfileArgs) -> Result<()> {
        instructions::platform_gate_fn(
            SerializableActions::PublicLow,
            None,
            &ctx.accounts.project,
            ctx.accounts.wallet.key(),
            ctx.accounts.wallet.to_account_info(),
            ctx.accounts.vault.to_account_info(),
            &None,
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.instructions_sysvar.to_account_info(),
            ID,
        )?;
        instructions::create_profile(ctx, args)
    }
    pub fn delete_profile(ctx: Context<DeleteProfile>) -> Result<()> {
        instructions::platform_gate_fn(
            SerializableActions::PublicLow,
            None,
            &ctx.accounts.project,
            ctx.accounts.wallet.key(),
            ctx.accounts.wallet.to_account_info(),
            ctx.accounts.vault.to_account_info(),
            &None,
            ctx.accounts.system_program.to_account_info(),
            ctx.accounts.instructions_sysvar.to_account_info(),
            ID,
        )?;
        instructions::delete_profile(ctx)
    }
    pub fn manage_profile_data(
        ctx: Context<ManageProfileData>,
        args: ManageProfileDataArgs,
    ) -> Result<()> {
        if args.value.is_some() {
            profile_platform_gate(
                &ctx.accounts.project,
                ctx.accounts.authority.key(),
                ctx.accounts.payer.to_account_info(),
                ctx.accounts.vault.to_account_info(),
                &ctx.accounts.delegate_authority,
                ctx.accounts.system_program.to_account_info(),
                ctx.accounts.instructions_sysvar.to_account_info(),
            )?;
        }
        instructions::manage_profile_data(ctx, args)
    }
    pub fn migrate_account(ctx: Context<MigrateAccount>, args: MigrateAccountArgs) -> Result<()> {
        instructions::migrate_account(ctx, args)
    }
    pub fn close_orphan_wallet_resolver(ctx: Context<CloseOrphanWalletResolver>) -> Result<()> {
        instructions::close_orphan_wallet_resolver(ctx)
    }
}