use std::{any::Any, collections::HashMap};
use cairo_vm::{
hint_processor::{
builtin_hint_processor::hint_utils::{insert_value_from_var_name, insert_value_into_ap},
hint_processor_definition::HintReference,
},
serde::deserialize_program::ApTracking,
types::exec_scope::ExecutionScopes,
vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
Felt252,
};
use crate::maybe_relocatable_box;
use cairo_vm::types::relocatable::MaybeRelocatable;
use super::{
types::MockCairoVerifierInput,
utils::{gen_arg, get_program_input_value},
vars::MOCK_CAIRO_VERIFIER_INPUT,
};
pub fn load_mock_cairo_verifier_input(
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> Result<(), HintError> {
let mock_cairo_verifier_input: MockCairoVerifierInput = get_program_input_value(exec_scopes)?;
let converted_args: Vec<Box<dyn Any>> = mock_cairo_verifier_input
.program_output
.iter()
.map(|item| maybe_relocatable_box!(*item))
.collect();
let output_base = gen_arg(vm, &converted_args)?;
insert_value_from_var_name("output", output_base, vm, ids_data, ap_tracking)?;
exec_scopes.insert_value(MOCK_CAIRO_VERIFIER_INPUT, mock_cairo_verifier_input);
Ok(())
}
pub fn mock_cairo_verifier_len_output_to_fp(
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
) -> Result<(), HintError> {
let mock_cairo_verifier_input: &MockCairoVerifierInput =
exec_scopes.get_ref(MOCK_CAIRO_VERIFIER_INPUT)?;
let output_len = mock_cairo_verifier_input.program_output.len();
let dest = (vm.get_fp() + 1)?;
Ok(vm.insert_value(dest, output_len)?)
}
pub fn mock_cairo_verifier_hash_to_fp(
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
) -> Result<(), HintError> {
let mock_cairo_verifier_input: &MockCairoVerifierInput =
exec_scopes.get_ref(MOCK_CAIRO_VERIFIER_INPUT)?;
let dest = (vm.get_fp() + 2)?;
Ok(vm.insert_value(dest, mock_cairo_verifier_input.program_hash)?)
}
pub fn mock_cairo_verifier_n_steps_to_ap(
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
) -> Result<(), HintError> {
let mock_cairo_verifier_input: &MockCairoVerifierInput =
exec_scopes.get_ref(MOCK_CAIRO_VERIFIER_INPUT)?;
let felt_n_steps =
Felt252::from_dec_str(&mock_cairo_verifier_input.n_steps.to_string()).unwrap();
insert_value_into_ap(vm, felt_n_steps)
}