package lab04;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class InstructionTest {
	Instruction testInstruction,testB;
	int binInstr;

	@BeforeEach
	void setUp() throws Exception {
		testInstruction=new Instruction("ADD","DIR",3);
		binInstr=Instruction.encodeOpModeArg(2, 1, 3);
		testB = new Instruction(binInstr);
	}

	@Test
	void testInstructionStringStringInt() { 
		assertEquals("ADD",testInstruction.getOpName());
		assertEquals(3,testInstruction.getOpcode());
		assertEquals("DIR",testInstruction.getModeName());
		assertEquals(1,testInstruction.getMode());
		assertEquals(3,testInstruction.getArgument());
	}

	@Test
	void testInstructionInt() { 
		assertEquals("STO",testB.getOpName());
		assertEquals(2,testB.getOpcode());
		assertEquals("DIR",testB.getModeName());
		assertEquals(1,testB.getMode());
		assertEquals(3,testB.getArgument());
	}

	@Test
	void testStore() { 
		Memory mem = new Memory(10);
		testB.store(mem, 4);
		int itest = mem.get(4);
		assertEquals(binInstr,itest,"Binary instruction successfully stored");
	}

	@Test
	void testGetOpName() { 
		assertEquals("ADD",testInstruction.getOpName());
		assertEquals("STO",testB.getOpName());
	}

	@Test
	void testGetOpcode() { 
		assertEquals(3,testInstruction.getOpcode());
		assertEquals(2,testB.getOpcode());
	}

	@Test
	void testGetModeName() { 
		assertEquals("DIR",testInstruction.getModeName());
		assertEquals("DIR",testB.getModeName());
	}

	@Test
	void testGetMode() { 
		assertEquals(1,testInstruction.getMode());
		assertEquals(1,testB.getMode());
	}

	@Test
	void testGetArgument() { 
		assertEquals(3,testInstruction.getArgument());
		assertEquals(3,testB.getArgument());
	}

	@Test
	void testFindOpcode() {
		assertEquals(0,Instruction.findOpcode("NOP"));
		assertEquals(1,Instruction.findOpcode("LOD"));
		assertEquals(2,Instruction.findOpcode("STO"));
		assertEquals(3,Instruction.findOpcode("ADD"));
		assertEquals(4,Instruction.findOpcode("SUB"));
		assertEquals(5,Instruction.findOpcode("MUL"));
		assertEquals(6,Instruction.findOpcode("DIV"));
		assertEquals(7,Instruction.findOpcode("HLT"));
		assertEquals(-1,Instruction.findOpcode("???"));
	}
	
	@Test
	void testFindMode() { 
		assertEquals(0,Instruction.findMode("IMM"));
		assertEquals(1,Instruction.findMode("DIR"));
		assertEquals(-1,Instruction.findMode("xxx"));
	}

}
