use std::sync::mpsc::{channel, Receiver, Sender};

use gb_emu_lib::{
    connect::{AudioOutput, EmulatorMessage, EmulatorOptions, RomFile},
    EmulatorCore,
};

pub struct TestEmulator {
    pub core: EmulatorCore<[u8; 4]>,
    pub _sender: Sender<EmulatorMessage<[u8; 4]>>,
    pub _audio_rx: async_ringbuf::AsyncHeapCons<[f32; 2]>,
    pub serial_rx: Receiver<u8>,
}

pub fn emulator_setup(rom_file: RomFile) -> anyhow::Result<TestEmulator> {
    let (sender, receiver) = channel::<EmulatorMessage<[u8; 4]>>();
    let rom = rom_file.load(gb_emu_lib::connect::SramType::None)?;
    let (audio_output, audio_rx) = AudioOutput::new(
        48000.,
        1,
        gb_emu_lib::connect::DownsampleType::ZeroOrderHold,
    );

    // let (tx_to_gameboy, rx_from_test) = channel::<u8>();
    let (tx_to_test, serial_rx) = channel::<u8>();

    let options = EmulatorOptions::new(None, rom, audio_output)
        .with_no_output(true)
        .with_serial_target(gb_emu_lib::connect::SerialTarget::Custom {
            rx: None,
            tx: Some(tx_to_test),
        })
        .with_cgb_bootrom(Some(RomFile::Raw(
            include_bytes!("../../../sameboy-bootroms/cgb_boot.bin").to_vec(),
        )))
        .with_dmg_bootrom(Some(RomFile::Raw(
            include_bytes!("../../../sameboy-bootroms/dmg_boot.bin").to_vec(),
        )));

    let core = EmulatorCore::init(true, receiver, options)?;
    sender.send(EmulatorMessage::Start)?;
    Ok(TestEmulator {
        core,
        _sender: sender,
        _audio_rx: audio_rx,
        serial_rx,
    })
}