// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x3a8, %rsp            # imm = 0x3A8
movq %rdi, %rbx
leaq 0x1a0(%rsp), %rdi
pushq $0x8
popq %rdx
movq %rbx, %rsi
callq 0x22d0
leaq 0x78(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
andq $0x0, 0x30(%rsp)
leaq 0x58(%rsp), %rcx
movq %rcx, -0x10(%rcx)
andq $0x0, -0x8(%rcx)
xorl %edx, %edx
movb %dl, (%rax)
movb %dl, (%rcx)
leaq 0x98(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movb %dl, (%rax)
leaq 0x218(%rsp), %rdi
callq 0x2080
testb %al, %al
je 0x2d63
leaq 0x20(%rbx), %rax
movq %rax, 0x10(%rsp)
addq $0x50, %rbx
movq %rbx, 0x40(%rsp)
movq $0x0, 0x18(%rsp)
leaq 0x1a0(%rsp), %r12
leaq 0x68(%rsp), %r13
movq %r12, %rdi
movq %r13, %rsi
callq 0x2050
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x2d19
cmpq $0x0, 0x70(%rsp)
je 0x2b2b
leaq 0xe8(%rsp), %rdi
movq %r13, %rsi
callq 0x2270
leaq 0x108(%rsp), %r14
movq %r14, %rdi
leaq 0x4544(%rip), %rsi      # 0x70b6
leaq 0xf(%rsp), %rdx
callq 0x30d4
leaq 0xa8(%rsp), %r15
movq %r15, %rdi
leaq 0xe8(%rsp), %rbp
movq %rbp, %rsi
movq %r14, %rdx
callq 0x3024
leaq 0x20(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x4bfe
movq %r15, %rdi
callq 0x3110
movq %r14, %rdi
callq 0x20e0
movq %rbp, %rdi
callq 0x20e0
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
cmpq $0x20, %rax
jbe 0x2da0
movq %rbx, %rdi
xorl %esi, %esi
callq 0x3132
leaq 0x48(%rsp), %rdi
movq %rax, %rsi
callq 0x2110
leaq 0x20(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x3132
leaq 0x88(%rsp), %rdi
movq %rax, %rsi
callq 0x2110
movq 0x10(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x3154
testq %rax, %rax
jne 0x2cd9
leaq 0x108(%rsp), %rdi
leaq 0x48(%rsp), %rbx
movq %rbx, %rsi
callq 0x5d46
movq 0x10(%rsp), %rdi
movq %rbx, %rsi
callq 0x316e
movq %rax, %rdi
leaq 0x108(%rsp), %rsi
callq 0x31d4
movq 0x936d(%rip), %rdi      # 0xbfc8
callq 0x20f0
movq %rax, %rbp
leaq 0xc8(%rsp), %rbx
movq %rbx, %rdi
leaq 0x4484(%rip), %rsi      # 0x70f9
leaq 0xf(%rsp), %rdx
callq 0x30d4
leaq 0xa8(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x321c
movq %rbp, %rdi
movq %r14, %rsi
callq 0x21c0
movq %rax, %rdi
leaq 0x48(%rsp), %rsi
callq 0x21c0
movq %rax, %rdi
callq 0x20f0
leaq 0xa8(%rsp), %rdi
callq 0x20e0
leaq 0xc8(%rsp), %rdi
callq 0x20e0
leaq 0x108(%rsp), %rdi
callq 0x32a2
movq 0x10(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x50c4
movq %rax, %rbp
addq $0x40, %rbp
movq %rbp, %rdi
leaq 0x88(%rsp), %rsi
callq 0x5dd4
movzwl %ax, %edx
movq 0x40(%rsp), %rdi
movq %rbp, %rsi
callq 0x5104
incq 0x18(%rsp)
jmp 0x2b2b
leaq 0x88(%rsp), %rdi
callq 0x20e0
leaq 0x48(%rsp), %rdi
callq 0x20e0
leaq 0x20(%rsp), %rdi
callq 0x3110
leaq 0x68(%rsp), %rdi
callq 0x20e0
leaq 0x1a0(%rsp), %rdi
callq 0x2090
addq $0x3a8, %rsp            # imm = 0x3A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x9286(%rip), %rdi      # 0xbff0
leaq 0x430d(%rip), %rsi      # 0x707e
callq 0x21d0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x21c0
leaq 0x42fd(%rip), %rsi      # 0x7085
movq %rax, %rdi
callq 0x21d0
movq %rax, %rdi
callq 0x20f0
pushq $-0x1
popq %rdi
callq 0x2230
movq 0x9249(%rip), %rdi      # 0xbff0
leaq 0x430b(%rip), %rsi      # 0x70b9
callq 0x21d0
movq %rax, %rdi
movq 0x18(%rsp), %rsi
callq 0x2150
leaq 0x4518(%rip), %rsi      # 0x72df
movq %rax, %rdi
callq 0x21d0
leaq 0x68(%rsp), %rsi
movq %rax, %rdi
callq 0x21c0
leaq 0x42e3(%rip), %rsi      # 0x70c6
movq %rax, %rdi
callq 0x21d0
movq %rax, %rdi
callq 0x20f0
jmp 0x2d98
jmp 0x2e45
movq %rax, %rbx
jmp 0x2e36
jmp 0x2e5d
jmp 0x2e5d
jmp 0x2e5d
movq %rax, %rbx
leaq 0x108(%rsp), %rdi
callq 0x20e0
jmp 0x2e17
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
callq 0x20e0
jmp 0x2e60
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
callq 0x20e0
leaq 0xc8(%rsp), %rdi
callq 0x20e0
jmp 0x2e48
movq %rax, %rbx
leaq 0x108(%rsp), %rdi
callq 0x32a2
jmp 0x2e60
jmp 0x2e5d
jmp 0x2e5d
jmp 0x2e5d
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x20e0
leaq 0x48(%rsp), %rdi
callq 0x20e0
leaq 0x20(%rsp), %rdi
callq 0x3110
leaq 0x68(%rsp), %rdi
callq 0x20e0
leaq 0x1a0(%rsp), %rdi
callq 0x2090
movq %rbx, %rdi
callq 0x2310