use crate::errors;
use anchor_lang::prelude::*;
use solana_address_lookup_table_program as solana_lut;
use solana_program::program::invoke_signed;
use super::close_task::Task;
pub use errors::*;
#[derive(Accounts)]
#[instruction(slot: u64, bump: u8)]
pub struct CreateLut<'info> {
#[account(mut)]
signer: Signer<'info>,
#[account(mut, seeds = ["payer".as_bytes(), &task.authority.key().to_bytes()[..]], bump)]
payer: UncheckedAccount<'info>,
#[account(constraint = authority.key() == task.authority.key())]
authority: UncheckedAccount<'info>,
#[account(mut, seeds =[&payer.key().to_bytes()[..], &slot.to_le_bytes()[..]], bump, seeds::program = solana_lut::id())]
lut: UncheckedAccount<'info>,
#[account(mut, seeds = ["task".as_bytes(), &task.parent_trigger.key().to_bytes()[..], &task.own_index.to_le_bytes()[..]], bump, constraint = task.lut.is_none() @ TriggrError::LookUpTableAlreadyExists)]
task: Account<'info, Task>,
address_lookup_table_program: UncheckedAccount<'info>,
system_program: Program<'info, System>,
}
pub fn handler(ctx: Context<CreateLut>, slot: u64, _bump: u8) -> Result<()> {
let (instruction, _pubkey) = solana_lut::instruction::create_lookup_table(
ctx.accounts.payer.key(),
ctx.accounts.payer.key(),
slot,
);
let payer_seeds = &[
"payer".as_bytes(),
&ctx.accounts.authority.key().to_bytes()[..],
&[ctx.bumps["payer"]],
];
let formated_payer_seeds = &[&payer_seeds[..]];
invoke_signed(
&instruction,
&[
ctx.accounts.lut.to_account_info(),
ctx.accounts.payer.to_account_info(),
ctx.accounts.payer.to_account_info(),
ctx.accounts.system_program.to_account_info(),
],
formated_payer_seeds,
)?;
let accounts = Task::collect_all_accounts(&ctx.accounts.task);
msg!("accounts: {:?}", accounts.len());
let account_slice = accounts.as_slice();
let num_iterations = (account_slice.len() + 26) / 27;
for i in 0..num_iterations {
let start_index = i * 27;
let end_index = (i + 1) * 27;
msg!("iteration: {}", i);
msg!("start index: {}", start_index);
msg!("end index: {}", end_index);
let slice = &account_slice[start_index..end_index.min(account_slice.len())];
let extend_instruction = solana_lut::instruction::extend_lookup_table(
ctx.accounts.lut.key(),
ctx.accounts.payer.key(),
Some(ctx.accounts.payer.key()),
slice.to_vec(),
);
invoke_signed(
&extend_instruction,
&[
ctx.accounts.lut.to_account_info(),
ctx.accounts.authority.to_account_info(),
ctx.accounts.payer.to_account_info(),
],
formated_payer_seeds,
)?;
}
ctx.accounts.task.lut = Some(ctx.accounts.lut.key());
Ok(())
}