// File: /workspace/github_cpp_makefile_star2_O3/isabellab3[P]OS-Simulation/main.cpp
// Function: main
int main() {

    unsigned int RAM = 0;
    unsigned int page_size = 0;
    int number_of_hard_disks = 0;

    std::cout << "How much RAM is there?" << std::endl;
    std::cin >> RAM;

    std::cout << "What is the size of a page/frame?" << std::endl;
    std::cin >> page_size;

    std::cout << "How many hard disks does the simulated computer have?" << std::endl;
    std::cin >> number_of_hard_disks;


    OperatingSystem OS(number_of_hard_disks, RAM, page_size);

    std::string input;
    std::getline(std::cin, input);

    while (1) {
         //Shows which process is currently using the CPU and which processes are waiting in the ready-queue.
        if (input == "S r") {
            OS.Snapshot();
        }
        //Shows which processes are currently using the hard disks and which processes are waiting to use them
        else if (input == "S i") {
            OS.IOSnapshot();
        }
        //Shows the state of memory.
        else if (input == "S m") {
            OS.MemorySnapshot();
        }
        // Creates a new pcb and places it at end of ready queue, or in the CPU if the ready queue is empty.
        else if (input == "A") {
            OS.CreateProcess();
        }
        //The currently running process has spent a time quantum using the CPU. 
        else if (input == "Q") {
            OS.CPUToReadyQueue();
        }
        //The process using the CPU forks a child.The child is placed in the end of the ready - queue.
        else if (input == "fork") {
            OS.Fork();
        }
        //The process that is currently using the CPU terminates.
        else if (input == "exit") {
            OS.Exit();
        }
        //The process wants to pause and wait for any of its child processes to terminate.
        else if (input == "wait") {
            OS.Wait();
        }
        
        // For other commands, parse input
        std::stringstream in_stream(input);
        string first_word;
        in_stream >> first_word;

        if (first_word == "d" || first_word == "D" || first_word == "m") {
            int second_word;
            in_stream >> second_word;
            //The process that currently uses the CPU requests the hard disk #number. 
            //It wants to read or write file file _name.
            if (first_word == "d") {
                string third_word;
                in_stream >> third_word;
                OS.RequestDisk(second_word, third_word);
            }
            else if (first_word == "D") { // "D number") {
                // The hard disk #number has finished the work for one process.
                OS.RemoveProcessFromDisk(second_word);
            }
            //The process that is currently using the CPU requests a memory operation for the logical address.
            else if (first_word == "m") { // == "m address") {
                OS.RequestMemoryOperation(second_word);
            }
        }       
        // Get next line of input from user
        std::cout << endl;
        std::getline(std::cin, input);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x298, %rsp            # imm = 0x298
xorl %eax, %eax
leaq 0x54(%rsp), %r14
movl %eax, (%r14)
leaq 0x50(%rsp), %r15
movl %eax, (%r15)
leaq 0x4c(%rsp), %r12
movl %eax, (%r12)
movq 0x5b91(%rip), %rbx      # 0x7fd0
leaq 0x2bbe(%rip), %rsi      # 0x5004
movl $0x16, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
movq 0x5b5f(%rip), %r13      # 0x7fe0
movq %r13, %rdi
movq %r14, %rsi
callq 0x2270
leaq 0x2b88(%rip), %rsi      # 0x501b
movl $0x21, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
movq %r13, %rdi
movq %r15, %rsi
callq 0x2270
leaq 0x2b64(%rip), %rsi      # 0x503d
movl $0x35, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
movq %r13, %rdi
movq %r12, %rsi
callq 0x20f0
leaq 0x78(%rsp), %rdi
movq %r12, %rsi
movq %r14, %rdx
movq %r15, %rcx
callq 0x28f4
leaq 0x68(%rsp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movq (%r13), %rax
addq -0x18(%rax), %r13
movq %r13, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %edx
movq 0x5a82(%rip), %r15      # 0x7fe0
leaq 0x58(%rsp), %rsi
movq %r15, %rdi
callq 0x22a0
leaq 0x58(%rsp), %r13
leaq 0x110(%rsp), %r14
leaq 0x28(%rsp), %r12
leaq 0x2b09(%rip), %rbp      # 0x508d
movq %r13, %rdi
leaq 0x2ae5(%rip), %rsi      # 0x5073
callq 0x2070
testl %eax, %eax
je 0x2634
movq %r13, %rdi
leaq 0x2ad2(%rip), %rsi      # 0x5077
callq 0x2070
testl %eax, %eax
je 0x2640
movq %r13, %rdi
leaq 0x2abf(%rip), %rsi      # 0x507b
callq 0x2070
testl %eax, %eax
je 0x264c
movq %r13, %rdi
leaq 0x2aac(%rip), %rsi      # 0x507f
callq 0x2070
testl %eax, %eax
je 0x2658
movq %r13, %rdi
leaq 0x2a9b(%rip), %rsi      # 0x5081
callq 0x2070
testl %eax, %eax
je 0x2664
movq %r13, %rdi
leaq 0x2bad(%rip), %rsi      # 0x51a6
callq 0x2070
testl %eax, %eax
je 0x2670
movq %r13, %rdi
leaq 0x2a77(%rip), %rsi      # 0x5083
callq 0x2070
testl %eax, %eax
je 0x267c
movq %r13, %rdi
leaq 0x2a69(%rip), %rsi      # 0x5088
callq 0x2070
testl %eax, %eax
jne 0x2686
leaq 0x78(%rsp), %rdi
callq 0x325c
jmp 0x2686
leaq 0x78(%rsp), %rdi
callq 0x2a8e
jmp 0x2686
leaq 0x78(%rsp), %rdi
callq 0x2b6e
jmp 0x2686
leaq 0x78(%rsp), %rdi
callq 0x2d60
jmp 0x2686
leaq 0x78(%rsp), %rdi
callq 0x2f2e
jmp 0x2686
leaq 0x78(%rsp), %rdi
callq 0x2faa
jmp 0x2686
leaq 0x78(%rsp), %rdi
callq 0x2ff6
jmp 0x2686
leaq 0x78(%rsp), %rdi
callq 0x30c2
movq %r14, %rdi
movq %r13, %rsi
movl $0x18, %edx
callq 0x2220
leaq 0x38(%rsp), %rax
movq %rax, 0x28(%rsp)
movq $0x0, 0x30(%rsp)
movb $0x0, 0x38(%rsp)
movq %r14, %rdi
movq %r12, %rsi
callq 0x21e0
movq %r12, %rdi
leaq 0x2a25(%rip), %rsi      # 0x50e8
callq 0x2070
testl %eax, %eax
je 0x26f2
movq %r12, %rdi
movq %rbp, %rsi
callq 0x2070
testl %eax, %eax
je 0x26f2
movq %r12, %rdi
leaq 0x2998(%rip), %rsi      # 0x507d
callq 0x2070
testl %eax, %eax
jne 0x27d4
movq %r14, %rdi
leaq 0x4(%rsp), %rsi
callq 0x20f0
movq %r12, %rdi
leaq 0x29df(%rip), %rsi      # 0x50e8
callq 0x2070
testl %eax, %eax
je 0x2750
movq %r12, %rdi
movq %rbp, %rsi
callq 0x2070
testl %eax, %eax
je 0x27c5
movq %r12, %rdi
leaq 0x294e(%rip), %rsi      # 0x507d
callq 0x2070
testl %eax, %eax
jne 0x27d4
leaq 0x78(%rsp), %rdi
leaq 0x4(%rsp), %rsi
callq 0x34bc
jmp 0x27d4
movq %r12, %r13
movq %r14, %rdi
movq %r15, %r12
movq %rbx, %r15
movq %rbp, %rbx
leaq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
movq $0x0, 0x10(%rsp)
movb $0x0, 0x18(%rsp)
leaq 0x8(%rsp), %rbp
movq %rbp, %rsi
callq 0x21e0
leaq 0x78(%rsp), %rdi
leaq 0x4(%rsp), %rsi
movq %rbp, %rdx
callq 0x3392
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x27b2
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21a0
movq %rbx, %rbp
movq %r15, %rbx
movq %r12, %r15
movq %r13, %r12
leaq 0x58(%rsp), %r13
jmp 0x27d4
leaq 0x78(%rsp), %rdi
leaq 0x4(%rsp), %rsi
callq 0x3430
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %edx
movq %r15, %rdi
movq %r13, %rsi
callq 0x22a0
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0x2839
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x21a0
movq %r14, %rdi
movq 0x5775(%rip), %rsi      # 0x7fb8
callq 0x2140
leaq 0x190(%rsp), %rdi
callq 0x2080
jmp 0x2584
movq %rax, %rbx
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x2884
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21a0
jmp 0x2884
jmp 0x28c3
jmp 0x28c3
jmp 0x2881
movq %rax, %rbx
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0x28a0
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x21a0
movq 0x5711(%rip), %rsi      # 0x7fb8
leaq 0x110(%rsp), %rdi
callq 0x2140
leaq 0x190(%rsp), %rdi
callq 0x2080
jmp 0x28c6
movq %rax, %rbx
movq 0x58(%rsp), %rdi
leaq 0x68(%rsp), %rax
cmpq %rax, %rdi
je 0x28e2
movq 0x68(%rsp), %rsi
incq %rsi
callq 0x21a0
leaq 0x78(%rsp), %rdi
callq 0x35d4
movq %rbx, %rdi
callq 0x2280