// File: /workspace/github_cpp_makefile_star2_O2/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
leaq 0x14(%rsp), %rbx
andl $0x0, (%rbx)
leaq 0x10(%rsp), %r14
andl $0x0, (%r14)
leaq 0xc(%rsp), %r15
andl $0x0, (%r15)
movq 0x5bb2(%rip), %r13      # 0x7fd0
leaq 0x2bdf(%rip), %rsi      # 0x5004
movq %r13, %rdi
callq 0x2190
movq %rax, %rdi
callq 0x20c0
movq 0x5ba4(%rip), %r12      # 0x7fe0
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2280
leaq 0x2bcd(%rip), %rsi      # 0x501b
movq %r13, %rdi
callq 0x2190
movq %rax, %rdi
callq 0x20c0
movq %r12, %rdi
movq %r14, %rsi
callq 0x2280
leaq 0x2bcd(%rip), %rsi      # 0x503d
movq %r13, %rdi
callq 0x2190
movq %rax, %rdi
callq 0x20c0
movq %r12, %rdi
movq %r15, %rsi
callq 0x2100
leaq 0x78(%rsp), %rdi
movq %r15, %rsi
movq %rbx, %rdx
movq %r14, %rcx
callq 0x2764
leaq 0x68(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x58(%rsp), %rsi
movq %r12, %rdi
callq 0x2050
leaq 0x58(%rsp), %r14
leaq 0x78(%rsp), %r15
leaq 0x110(%rsp), %r12
leaq 0x18(%rsp), %r13
leaq 0x2c0e(%rip), %rbx      # 0x50e8
leaq 0x2bac(%rip), %rbp      # 0x508d
movq %r14, %rdi
leaq 0x2b88(%rip), %rsi      # 0x5073
callq 0x28cf
testb %al, %al
je 0x2501
movq %r15, %rdi
callq 0x28dc
jmp 0x25d0
movq %r14, %rdi
leaq 0x2b6c(%rip), %rsi      # 0x5077
callq 0x28cf
testb %al, %al
je 0x2521
movq %r15, %rdi
callq 0x2966
jmp 0x25d0
movq %r14, %rdi
leaq 0x2b50(%rip), %rsi      # 0x507b
callq 0x28cf
testb %al, %al
je 0x2541
movq %r15, %rdi
callq 0x2ab8
jmp 0x25d0
movq %r14, %rdi
leaq 0x2b34(%rip), %rsi      # 0x507f
callq 0x28cf
testb %al, %al
je 0x255e
movq %r15, %rdi
callq 0x2c02
jmp 0x25d0
movq %r14, %rdi
leaq 0x2b19(%rip), %rsi      # 0x5081
callq 0x28cf
testb %al, %al
je 0x257b
movq %r15, %rdi
callq 0x2c90
jmp 0x25d0
movq %r14, %rdi
leaq 0x2c21(%rip), %rsi      # 0x51a6
callq 0x28cf
testb %al, %al
je 0x2598
movq %r15, %rdi
callq 0x2cbe
jmp 0x25d0
movq %r14, %rdi
leaq 0x2ae1(%rip), %rsi      # 0x5083
callq 0x28cf
testb %al, %al
je 0x25b5
movq %r15, %rdi
callq 0x2d6e
jmp 0x25d0
movq %r14, %rdi
leaq 0x2ac9(%rip), %rsi      # 0x5088
callq 0x28cf
testb %al, %al
je 0x25d0
movq %r15, %rdi
callq 0x2e94
movq %r12, %rdi
movq %r14, %rsi
pushq $0x18
popq %rdx
callq 0x2230
leaq 0x28(%rsp), %rax
movq %rax, 0x18(%rsp)
andq $0x0, 0x20(%rsp)
movb $0x0, 0x28(%rsp)
movq %r12, %rdi
movq %r13, %rsi
callq 0x21e0
movq %r13, %rdi
movq %rbx, %rsi
callq 0x28cf
testb %al, %al
jne 0x2633
movq %r13, %rdi
movq %rbp, %rsi
callq 0x28cf
testb %al, %al
jne 0x2633
movq %r13, %rdi
leaq 0x2a57(%rip), %rsi      # 0x507d
callq 0x28cf
testb %al, %al
je 0x26e3
movq %r12, %rdi
leaq 0x8(%rsp), %rsi
callq 0x2100
movq %r13, %rdi
movq %rbx, %rsi
callq 0x28cf
testb %al, %al
je 0x26a5
movq %r12, %rdi
movq %r14, %r13
movq %rbx, %r14
movq %rbp, %rbx
leaq 0x48(%rsp), %rax
movq %rax, 0x38(%rsp)
andq $0x0, 0x40(%rsp)
movb $0x0, 0x48(%rsp)
leaq 0x38(%rsp), %rbp
movq %rbp, %rsi
callq 0x21e0
movq %r15, %rdi
leaq 0x8(%rsp), %rsi
movq %rbp, %rdx
callq 0x2f6a
movq %rbp, %rdi
callq 0x20b0
movq %rbx, %rbp
movq %r14, %rbx
movq %r13, %r14
leaq 0x18(%rsp), %r13
jmp 0x26e3
movq %r13, %rdi
movq %rbp, %rsi
callq 0x28cf
testb %al, %al
je 0x26c3
movq %r15, %rdi
leaq 0x8(%rsp), %rsi
callq 0x2fde
jmp 0x26e3
movq %r13, %rdi
leaq 0x29b0(%rip), %rsi      # 0x507d
callq 0x28cf
testb %al, %al
je 0x26e3
movq %r15, %rdi
leaq 0x8(%rsp), %rsi
callq 0x3040
movq 0x58e6(%rip), %rdi      # 0x7fd0
callq 0x20c0
movq 0x58ea(%rip), %rdi      # 0x7fe0
movq %r14, %rsi
callq 0x2050
movq %r13, %rdi
callq 0x20b0
movq %r12, %rdi
callq 0x2140
jmp 0x24e1
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x20b0
jmp 0x272b
jmp 0x2744
jmp 0x2744
jmp 0x2728
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x20b0
leaq 0x110(%rsp), %rdi
callq 0x2140
jmp 0x2747
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0x20b0
leaq 0x78(%rsp), %rdi
callq 0x3116
movq %rbx, %rdi
callq 0x2290
nop