// File: gibsjose[P]VirtualMemorySimulation/Simulation.cpp
// Function: Simulation::Run()
void Simulation::Run(void) {
    //Read in the input file
    std::ifstream file(filepath);
    std::string line;
    std::vector<std::string> values;
    std::string name;
    std::string pageString;

    unsigned long lineNumber = 0;
    uint16_t frame;

    if(!file.is_open()) {
        std::cerr << "File \"" << filepath << "\" could not be opened. Check to see if it exists" << std::endl;
        exit(-1);
    }

    //Iterate over each line of the file
    while(std::getline(file, line)) {

        //Skip blank lines
        if(line.empty()) {
            continue;
        }

        values = StringUtilities::SplitString(line, ":\t");

        if(values.size() < 2) {
            std::cerr << "Error: Line " << lineNumber << ": \"" << line << "\" does not follow format of \"{NAME}:<TAB>{Page #}\"" << std::endl;
            exit(-1);
        }

        name = values.at(0);
        pageString = values.at(1);

        //New process: Add it to the map
        if(!processes.count(name)) {
            Process process(name);
            processes[name] = process;

            std::cout << std::endl << Color::Green("* [NEW PROCESS] ") << name << std::endl;
        }

        //Get the process object
        Process & process = processes.find(name)->second;
        uint16_t page = process.PageAccess(pageString);

        //Reference the process page in memory
        // This could result in one of three things:
        // 1. There is already a frame associated with the page number, and it is already in memory
        // 2. There is already a frame associated with the page number, and it is on the free frame list
        // 3. There is no frame associated with this page number --> Page fault: Assign it a page number and bring frame into
        //     memory
        memory.Reference(process, page);

        //Increment line number
        lineNumber++;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4c0, %rsp            # imm = 0x4C0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rsi
movq %rsi, -0x410(%rbp)
leaq -0x210(%rbp), %rdi
movq %rdi, -0x408(%rbp)
movl $0x8, %edx
callq 0x33d0
leaq -0x230(%rbp), %rdi
callq 0x3360
leaq -0x248(%rbp), %rdi
callq 0x4a90
leaq -0x268(%rbp), %rdi
callq 0x3360
leaq -0x288(%rbp), %rdi
callq 0x3360
movq -0x408(%rbp), %rdi
movq $0x0, -0x290(%rbp)
callq 0x33c0
movb %al, -0x3fb(%rbp)
jmp 0x4051
movb -0x3fb(%rbp), %al
testb $0x1, %al
jne 0x40eb
jmp 0x4061
movq 0x17f88(%rip), %rdi     # 0x1bff0
leaq 0xe033(%rip), %rsi      # 0x120a2
callq 0x3230
movq %rax, -0x418(%rbp)
jmp 0x407d
movq -0x410(%rbp), %rsi
movq -0x418(%rbp), %rdi
callq 0x3220
movq %rax, -0x420(%rbp)
jmp 0x4099
movq -0x420(%rbp), %rdi
leaq 0xe002(%rip), %rsi      # 0x120a9
callq 0x3230
movq %rax, -0x428(%rbp)
jmp 0x40b5
movq -0x428(%rbp), %rdi
movq 0x17ef5(%rip), %rsi     # 0x1bfb8
callq 0x3280
jmp 0x40ca
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x32f0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2a0(%rbp)
movl %eax, -0x2a4(%rbp)
jmp 0x4625
jmp 0x40ed
leaq -0x210(%rbp), %rdi
leaq -0x230(%rbp), %rsi
callq 0x3070
movq %rax, -0x430(%rbp)
jmp 0x4109
movq -0x430(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x3310
movb %al, -0x431(%rbp)
jmp 0x4127
movb -0x431(%rbp), %al
testb $0x1, %al
jne 0x4136
jmp 0x45e0
leaq -0x230(%rbp), %rdi
callq 0x3400
testb $0x1, %al
jne 0x4148
jmp 0x414a
jmp 0x40ed
leaq -0x2e0(%rbp), %rdi
leaq -0x230(%rbp), %rsi
callq 0x30f0
jmp 0x415f
leaq -0x301(%rbp), %rdi
movq %rdi, -0x440(%rbp)
callq 0x3440
movq -0x440(%rbp), %rdx
leaq 0xdf5a(%rip), %rsi      # 0x120da
leaq -0x300(%rbp), %rdi
callq 0x4de0
jmp 0x418e
leaq -0x2c0(%rbp), %rdi
leaq -0x2e0(%rbp), %rsi
leaq -0x300(%rbp), %rdx
callq 0x4ab0
jmp 0x41aa
leaq -0x248(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
callq 0x4e90
leaq -0x2c0(%rbp), %rdi
callq 0x4ec0
leaq -0x300(%rbp), %rdi
callq 0x3170
leaq -0x301(%rbp), %rdi
callq 0x32a0
leaq -0x2e0(%rbp), %rdi
callq 0x3170
leaq -0x248(%rbp), %rdi
callq 0x4f20
cmpq $0x2, %rax
jae 0x42fd
movq 0x17de6(%rip), %rdi     # 0x1bff0
leaq 0xdecc(%rip), %rsi      # 0x120dd
callq 0x3230
movq %rax, -0x448(%rbp)
jmp 0x421f
movq -0x448(%rbp), %rdi
movq -0x290(%rbp), %rsi
callq 0x30a0
movq %rax, -0x450(%rbp)
jmp 0x423b
movq -0x450(%rbp), %rdi
leaq 0xe136(%rip), %rsi      # 0x1237f
callq 0x3230
movq %rax, -0x458(%rbp)
jmp 0x4257
movq -0x458(%rbp), %rdi
leaq -0x230(%rbp), %rsi
callq 0x3220
movq %rax, -0x460(%rbp)
jmp 0x4273
movq -0x460(%rbp), %rdi
leaq 0xde69(%rip), %rsi      # 0x120ea
callq 0x3230
movq %rax, -0x468(%rbp)
jmp 0x428f
movq -0x468(%rbp), %rdi
movq 0x17d1b(%rip), %rsi     # 0x1bfb8
callq 0x3280
jmp 0x42a4
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x32f0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2a0(%rbp)
movl %eax, -0x2a4(%rbp)
jmp 0x42e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2a0(%rbp)
movl %eax, -0x2a4(%rbp)
leaq -0x300(%rbp), %rdi
callq 0x3170
leaq -0x301(%rbp), %rdi
callq 0x32a0
leaq -0x2e0(%rbp), %rdi
callq 0x3170
jmp 0x4625
xorl %eax, %eax
movl %eax, %esi
leaq -0x248(%rbp), %rdi
callq 0x4f40
movq %rax, -0x470(%rbp)
jmp 0x4316
movq -0x470(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x3040
jmp 0x432b
leaq -0x248(%rbp), %rdi
movl $0x1, %esi
callq 0x4f40
movq %rax, -0x478(%rbp)
jmp 0x4345
movq -0x478(%rbp), %rsi
leaq -0x288(%rbp), %rdi
callq 0x3040
jmp 0x435a
movq -0x410(%rbp), %rdi
addq $0x20, %rdi
leaq -0x268(%rbp), %rsi
callq 0x4f80
movq %rax, -0x480(%rbp)
jmp 0x437a
movq -0x480(%rbp), %rax
cmpq $0x0, %rax
jne 0x453a
leaq -0x3a0(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0xf980
jmp 0x43a0
movq -0x410(%rbp), %rdi
addq $0x20, %rdi
leaq -0x268(%rbp), %rsi
callq 0x4fe0
movq %rax, -0x488(%rbp)
jmp 0x43c0
movq -0x488(%rbp), %rdi
leaq -0x3a0(%rbp), %rsi
callq 0x50c0
jmp 0x43d5
movq 0x17bec(%rip), %rdi     # 0x1bfc8
movq 0x17bd5(%rip), %rsi     # 0x1bfb8
callq 0x3280
movq %rax, -0x490(%rbp)
jmp 0x43f1
leaq -0x3e1(%rbp), %rdi
movq %rdi, -0x498(%rbp)
callq 0x3440
movq -0x498(%rbp), %rdx
leaq 0xdd0b(%rip), %rsi      # 0x1211d
leaq -0x3e0(%rbp), %rdi
callq 0x4de0
jmp 0x4420
leaq -0x3c0(%rbp), %rdi
leaq -0x3e0(%rbp), %rsi
callq 0x5130
jmp 0x4435
movq -0x490(%rbp), %rdi
leaq -0x3c0(%rbp), %rsi
callq 0x3220
movq %rax, -0x4a0(%rbp)
jmp 0x4451
movq -0x4a0(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x3220
movq %rax, -0x4a8(%rbp)
jmp 0x446d
movq -0x4a8(%rbp), %rdi
movq 0x17b3d(%rip), %rsi     # 0x1bfb8
callq 0x3280
jmp 0x4482
leaq -0x3c0(%rbp), %rdi
callq 0x3170
leaq -0x3e0(%rbp), %rdi
callq 0x3170
leaq -0x3e1(%rbp), %rdi
callq 0x32a0
leaq -0x3a0(%rbp), %rdi
callq 0x51e0
jmp 0x453a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2a0(%rbp)
movl %eax, -0x2a4(%rbp)
jmp 0x4529
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2a0(%rbp)
movl %eax, -0x2a4(%rbp)
jmp 0x451d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2a0(%rbp)
movl %eax, -0x2a4(%rbp)
jmp 0x4511
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2a0(%rbp)
movl %eax, -0x2a4(%rbp)
leaq -0x3c0(%rbp), %rdi
callq 0x3170
leaq -0x3e0(%rbp), %rdi
callq 0x3170
leaq -0x3e1(%rbp), %rdi
callq 0x32a0
leaq -0x3a0(%rbp), %rdi
callq 0x51e0
jmp 0x4625
movq -0x410(%rbp), %rdi
addq $0x20, %rdi
leaq -0x268(%rbp), %rsi
callq 0x5220
movq %rax, -0x4b0(%rbp)
jmp 0x455a
movq -0x4b0(%rbp), %rax
movq %rax, -0x3f8(%rbp)
leaq -0x3f8(%rbp), %rdi
callq 0x5250
addq $0x20, %rax
movq %rax, -0x3f0(%rbp)
movq -0x3f0(%rbp), %rdi
leaq -0x288(%rbp), %rsi
callq 0xfa40
movw %ax, -0x4b2(%rbp)
jmp 0x459b
movq -0x410(%rbp), %rdi
movw -0x4b2(%rbp), %ax
movw %ax, -0x3fa(%rbp)
addq $0x50, %rdi
movq -0x3f0(%rbp), %rsi
movzwl -0x3fa(%rbp), %edx
callq 0xd8e0
jmp 0x45c9
movq -0x290(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x290(%rbp)
jmp 0x40ed
leaq -0x288(%rbp), %rdi
callq 0x3170
leaq -0x268(%rbp), %rdi
callq 0x3170
leaq -0x248(%rbp), %rdi
callq 0x4ec0
leaq -0x230(%rbp), %rdi
callq 0x3170
leaq -0x210(%rbp), %rdi
callq 0x30b0
addq $0x4c0, %rsp            # imm = 0x4C0
popq %rbp
retq
leaq -0x288(%rbp), %rdi
callq 0x3170
leaq -0x268(%rbp), %rdi
callq 0x3170
leaq -0x248(%rbp), %rdi
callq 0x4ec0
leaq -0x230(%rbp), %rdi
callq 0x3170
leaq -0x210(%rbp), %rdi
callq 0x30b0
movq -0x2a0(%rbp), %rdi
callq 0x3430
nopl (%rax)