// File: sidvishnoi[P]filesystem-assignment/day3/createFile.cpp
// Function: FileSystem::createFile(char const*, char const*)
int FileSystem::createFile(const char *title, const char *srcFile) {
    /*
    Objective: To create a file
    Input parameters:
        title:  file name
        srcfile: file to read data from
    Return value:
        0: success
        1: failure
    Effect: a new file is created in filesystem and it's entry is passed in current working directory
     */

    TypeCastEntry entry;
    if (strlen(title) == 0) {
        // %% get file name from user and store it in entry.entry.name
    } else {
        strcpy(entry.entry.name, title);
    }

    /* %% use alreadyExists() to check for duplicate entry) */
    bool fileAlreadyExists; // %%

    if(fileAlreadyExists) {
        cout << "ERROR: File <" << entry.entry.name<< "> already exists!" << endl;
        return 1;
    }

    vector<int>offset = getEntryPosition();

    /* %% use offset to check if space for file entry is available */
    bool enoughSpaceForEntry;
    if(enoughSpaceForEntry) {
        cout << "ERROR: Not enough space for file entry." << endl;
        return 1;
    }

    // file contents & size
    char file_content[MAX_FILE_SIZE];

    if (strlen(srcFile) == 0) {
        // if source file is not given
        // %% get data from user into file_content and calculate size in bytes to entry.entry.size
    } else {
        ifstream fsrc;
        fsrc.open(srcFile, ios::binary | ios::in);
        // %% read the content from source file into file_content and calculate size (bytes)
        fsrc.close();
    }

    if (entry.entry.size < 0) return 1;

    // find sectors to write in
    int sectorsNeeded = (entry.entry.size - 1) / sectorSize_k + 1;
    vector<int> sectorsFree = findEmptySectors(sectorsNeeded);

    // %% check if vector returned is empty
    bool enoughSectors;
    if (!enoughSectors) {
        cout << "ERROR: Not enough memory!" << endl;
        return 1;
    }

    // %% fill details of file entry (parent, file type)
    // parent is sector corresponding to (current) root directory
    entry.entry.startsAt = sectorsFree[0];

    writeEntry(offset, entry.str);

    char buf[sectorSize_k];
    // write data and update sector status
    for (int i = 0; i < sectorsNeeded; ++i) {
        for (int j = 0; j < sectorSize_k; ++j) {
            buf[j] = file_content[sectorSize_k*i + j];
        }
        writeSector(sectorsFree[i], buf);
        // we use index of next sector as status of sector as a pointer to show continuation,
        //   last sectors gets status 1
        setStatus(sectorsFree[i], (i != sectorsNeeded-1) ? sectorsFree[i+1] : 1);
    }
    // %% display information about the file created
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x720, %rsp            # imm = 0x720
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x6e8(%rbp)
movq -0x18(%rbp), %rdi
callq 0x30d0
cmpq $0x0, %rax
jne 0x9c73
jmp 0x9c84
leaq -0x44(%rbp), %rdi
addq $0x10, %rdi
movq -0x18(%rbp), %rsi
callq 0x3220
testb $0x1, -0x45(%rbp)
je 0x9cd7
movq 0x733f(%rip), %rdi      # 0x10fd0
leaq 0x269b(%rip), %rsi      # 0xc333
callq 0x3230
movq %rax, %rdi
leaq -0x44(%rbp), %rsi
addq $0x10, %rsi
callq 0x3230
movq %rax, %rdi
leaq 0x268a(%rip), %rsi      # 0xc341
callq 0x3230
movq %rax, %rdi
movq 0x72fa(%rip), %rsi      # 0x10fc0
callq 0x3260
movl $0x1, -0x4(%rbp)
jmp 0xa09a
movq -0x6e8(%rbp), %rsi
leaq -0x60(%rbp), %rdi
callq 0x98e0
testb $0x1, -0x61(%rbp)
je 0x9d42
movq 0x72dc(%rip), %rdi      # 0x10fd0
leaq 0x2658(%rip), %rsi      # 0xc353
callq 0x3230
movq %rax, -0x6f0(%rbp)
jmp 0x9d09
movq -0x6f0(%rbp), %rdi
movq 0x72a9(%rip), %rsi      # 0x10fc0
callq 0x3260
jmp 0x9d1e
movl $0x1, -0x4(%rbp)
movl $0x1, -0x78(%rbp)
jmp 0xa084
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xa08f
movq -0x20(%rbp), %rdi
callq 0x30d0
cmpq $0x0, %rax
jne 0x9d56
jmp 0x9dda
leaq -0x688(%rbp), %rdi
callq 0x32b0
jmp 0x9d64
movq -0x20(%rbp), %rax
movq %rax, -0x700(%rbp)
movl $0x4, %edi
movl $0x8, %esi
callq 0x62a0
movl %eax, -0x6f4(%rbp)
jmp 0x9d86
movl -0x6f4(%rbp), %edx
movq -0x700(%rbp), %rsi
leaq -0x688(%rbp), %rdi
callq 0x3160
jmp 0x9da1
leaq -0x688(%rbp), %rdi
callq 0x3060
jmp 0x9daf
leaq -0x688(%rbp), %rdi
callq 0x3070
jmp 0x9dda
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x688(%rbp), %rdi
callq 0x3070
jmp 0xa08f
cmpl $0x0, -0x40(%rbp)
jge 0x9df3
movl $0x1, -0x4(%rbp)
movl $0x1, -0x78(%rbp)
jmp 0xa084
movq -0x6e8(%rbp), %rsi
movl -0x40(%rbp), %eax
decl %eax
movl 0x20(%rsi), %ecx
cltd
idivl %ecx
incl %eax
movl %eax, -0x68c(%rbp)
movl -0x68c(%rbp), %edx
leaq -0x6a8(%rbp), %rdi
callq 0x85f0
jmp 0x9e21
testb $0x1, -0x6a9(%rbp)
jne 0x9e7f
movq 0x719f(%rip), %rdi      # 0x10fd0
leaq 0x2543(%rip), %rsi      # 0xc37b
callq 0x3230
movq %rax, -0x708(%rbp)
jmp 0x9e46
movq -0x708(%rbp), %rdi
movq 0x716c(%rip), %rsi      # 0x10fc0
callq 0x3260
jmp 0x9e5b
movl $0x1, -0x4(%rbp)
movl $0x1, -0x78(%rbp)
jmp 0xa068
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xa076
xorl %eax, %eax
movl %eax, %esi
leaq -0x6a8(%rbp), %rdi
callq 0x9c20
movl (%rax), %eax
movl %eax, -0x44(%rbp)
leaq -0x6c8(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0xa0b0
jmp 0x9ea6
movq -0x6e8(%rbp), %rdi
leaq -0x6c8(%rbp), %rsi
leaq -0x44(%rbp), %rdx
callq 0x9b80
jmp 0x9ebf
leaq -0x6c8(%rbp), %rdi
callq 0x3db0
movq -0x6e8(%rbp), %rax
movl 0x20(%rax), %eax
movq %rsp, %rcx
movq %rcx, -0x6d0(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x710(%rbp)
movq %rcx, %rsp
movq %rax, -0x6d8(%rbp)
movl $0x0, -0x6dc(%rbp)
movl -0x6dc(%rbp), %eax
cmpl -0x68c(%rbp), %eax
jge 0xa050
movl $0x0, -0x6e0(%rbp)
movq -0x6e8(%rbp), %rcx
movl -0x6e0(%rbp), %eax
cmpl 0x20(%rcx), %eax
jge 0x9f99
movq -0x710(%rbp), %rax
movq -0x6e8(%rbp), %rcx
movl 0x20(%rcx), %ecx
imull -0x6dc(%rbp), %ecx
addl -0x6e0(%rbp), %ecx
movslq %ecx, %rcx
movb -0x480(%rbp,%rcx), %dl
movslq -0x6e0(%rbp), %rcx
movb %dl, (%rax,%rcx)
movl -0x6e0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6e0(%rbp)
jmp 0x9f27
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x6c8(%rbp), %rdi
callq 0x3db0
jmp 0xa076
movslq -0x6dc(%rbp), %rsi
leaq -0x6a8(%rbp), %rdi
callq 0x9c20
movq -0x6e8(%rbp), %rdi
movq -0x710(%rbp), %rdx
movl (%rax), %esi
callq 0x8160
jmp 0x9fc3
movslq -0x6dc(%rbp), %rsi
leaq -0x6a8(%rbp), %rdi
callq 0x9c20
movl (%rax), %eax
movl %eax, -0x714(%rbp)
movl -0x6dc(%rbp), %eax
movl -0x68c(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
je 0xa013
movl -0x6dc(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
leaq -0x6a8(%rbp), %rdi
callq 0x9c20
movl (%rax), %eax
movl %eax, -0x718(%rbp)
jmp 0xa020
movl $0x1, %eax
movl %eax, -0x718(%rbp)
jmp 0xa020
movl -0x714(%rbp), %esi
movq -0x6e8(%rbp), %rdi
movl -0x718(%rbp), %edx
callq 0x84b0
jmp 0xa03a
jmp 0xa03c
movl -0x6dc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6dc(%rbp)
jmp 0x9f0b
movl $0x0, -0x4(%rbp)
movl $0x1, -0x78(%rbp)
movq -0x6d0(%rbp), %rax
movq %rax, %rsp
leaq -0x6a8(%rbp), %rdi
callq 0x3db0
jmp 0xa084
leaq -0x6a8(%rbp), %rdi
callq 0x3db0
jmp 0xa08f
leaq -0x60(%rbp), %rdi
callq 0x3db0
jmp 0xa09a
leaq -0x60(%rbp), %rdi
callq 0x3db0
jmp 0xa0a2
movl -0x4(%rbp), %eax
movq %rbp, %rsp
popq %rbp
retq
movq -0x70(%rbp), %rdi
callq 0x3450
nopl (%rax,%rax)