use p101_is::*;
use crate::alu::*;
use crate::message::*;
use std::sync::mpsc;
use rust_decimal::Decimal;

fn alu_with_p1(p1: [Option<Instruction>; 24], ip: usize) -> (DefaultAlu, mpsc::Receiver<Message>) {
    let memory = MemoryBuilder::new()
        .with_p1(p1)
        .with_ip(ip)
        .build();
    
    let (sender, receiver) = mpsc::channel();

    let alu = DefaultAlu::new_with_memory(sender, memory);

    (alu, receiver)
}

#[test]
fn coding_31_68() {

    // Arrange

    const P1: [Option<Instruction>; 24] = [
        Some(Instruction::CopyM(p101_is::Register::A)), 
        Some(Instruction::Cai(CaiSign::Positive, CaiOrder::Low, CaiDigit::N8, CaiComma::No)),
        Some(Instruction::Cai(CaiSign::Positive, CaiOrder::Low, CaiDigit::N6, CaiComma::No)),
        Some(Instruction::Cai(CaiSign::Positive, CaiOrder::Low, CaiDigit::N1, CaiComma::Yes)),
        Some(Instruction::Cai(CaiSign::Positive, CaiOrder::High, CaiDigit::N3, CaiComma::No)),
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
    ];

    let (mut alu, _receiver) = alu_with_p1(P1, 0_usize);

    // Act

    let result = alu.copy_m(p101_is::Register::A);

    // Assert

    assert_eq!(Ok(()), result);
    assert_eq!(Decimal::new(3168, 2), alu.memory.m.read());
}
