// File: margual56[P]Markdown-CLI/src/main.cpp
// Function: main
int main(int argc, char **argv) {
    int c;
    std::string styleFile, inputFile, outputFile, stdinMarkdown;
    bool verbose_flag;

    while (1) {
        static struct option long_options[] = {
            {"verbose",     no_argument,        0, 'v'},
            {"help",        no_argument,        0, 'h'},
            {"style",       required_argument,  0, 's'},
            {"input",       required_argument,  0, 'i'}
        };

        /* getopt_long stores the option index here. */
        int option_index = 0;

        c = getopt_long(argc, argv, "vhs:i:", long_options, &option_index);

        /* Detect the end of the options. */
        if (c == -1)
            break;

        switch (c) {
            case 'v':
                verbose_flag = true;
            break;

            case 'h':
                printf("Gotta show the man page (or the help)");
                exit(0);
            break;

            case 's':
                styleFile = optarg;
            break;

            case 'i':
                inputFile = optarg;
            break;

            default:
                abort();
        }
    }

    if (verbose_flag)
        puts("Verbose flag is set");

    if (optind+1 < argc) {
        perror("Too many arguments\n");
        exit(2);
    }

    if(inputFile.empty()){
        printf("Input: stdin\nPress Ctrl+D (or Ctrl+Z on Windows) to end.\n");

        // Read from stdin and load it into a variable
        std::string line;
        do{
            std::getline(std::cin, line);
            stdinMarkdown += line + "\n";
        }while(!std::cin.eof());
    }else{
        std::ifstream inputStream(inputFile);

        if(inputStream.is_open()){
            std::string line;
            do{
                std::getline(inputStream, line);
                stdinMarkdown += line + "\n";
            }while(!inputStream.eof());

            inputStream.close();
        }else{
            printf("%s\n", outputFile.c_str());
            perror("Unable to open the output file");
            exit(3);
        }

        if(verbose_flag)
            printf("Input: %s\n", inputFile.c_str());
    }

    //printf("%s\n", stdinMarkdown.c_str());

    HTML *output = new HTML(markdown(stdinMarkdown));

    if(!styleFile.empty() && verbose_flag){
        printf("Style: %s\n", styleFile.c_str());
    }

    if(optind < argc){
        outputFile = std::string(argv[optind]);
        if(verbose_flag)
            printf("Output: %s\n", outputFile.c_str());

        std::ofstream outputStream (outputFile);
        if(outputStream.is_open()){
            outputStream << output->render();
            outputStream.close();
        }else{
            printf("%s\n", outputFile.c_str());
            perror("Unable to open the output file");
            exit(3);
        }
    }else{
        if(verbose_flag)
            printf("Output: stdout\n\n");

        printf("%s\n", output->render().c_str());
    }


    exit(0);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x620, %rsp            # imm = 0x620
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x5570
leaq -0x58(%rbp), %rdi
callq 0x5570
leaq -0x78(%rbp), %rdi
callq 0x5570
leaq -0x98(%rbp), %rdi
callq 0x5570
jmp 0x7a52
movl $0x0, -0xa0(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x2b67b(%rip), %rdx     # 0x330e5
leaq 0x4499f(%rip), %rcx     # 0x4c410
leaq -0xa0(%rbp), %r8
callq 0x5680
movl %eax, -0x14(%rbp)
cmpl $-0x1, -0x14(%rbp)
jne 0x7a8b
jmp 0x7b25
movl -0x14(%rbp), %eax
addl $-0x68, %eax
movl %eax, %ecx
movq %rcx, -0x5f8(%rbp)
subl $0xe, %eax
ja 0x7b1b
movq -0x5f8(%rbp), %rax
leaq 0x2b5e3(%rip), %rcx     # 0x33090
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x1, -0x99(%rbp)
jmp 0x7b20
leaq 0x2b626(%rip), %rdi     # 0x330ec
xorl %eax, %eax
callq 0x5070
jmp 0x7acf
xorl %edi, %edi
callq 0x54e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x81a5
movq 0x4449c(%rip), %rax     # 0x4bf90
movq (%rax), %rsi
leaq -0x38(%rbp), %rdi
callq 0x5560
jmp 0x7b02
jmp 0x7b20
movq 0x44485(%rip), %rax     # 0x4bf90
movq (%rax), %rsi
leaq -0x58(%rbp), %rdi
callq 0x5560
jmp 0x7b19
jmp 0x7b20
callq 0x5250
jmp 0x7a50
testb $0x1, -0x99(%rbp)
je 0x7b3e
leaq 0x2b5dd(%rip), %rdi     # 0x33112
callq 0x5600
jmp 0x7b3c
jmp 0x7b3e
movq 0x44473(%rip), %rax     # 0x4bfb8
movl (%rax), %eax
addl $0x1, %eax
cmpl -0x8(%rbp), %eax
jge 0x7b67
leaq 0x2b5d0(%rip), %rdi     # 0x33126
callq 0x5390
jmp 0x7b5d
movl $0x2, %edi
callq 0x54e0
leaq -0x58(%rbp), %rdi
callq 0x5690
testb $0x1, %al
jne 0x7b79
jmp 0x7c65
leaq 0x2b5ba(%rip), %rdi     # 0x3313a
xorl %eax, %eax
callq 0x5070
jmp 0x7b89
leaq -0xd0(%rbp), %rdi
callq 0x5570
movq 0x44444(%rip), %rdi     # 0x4bfe0
leaq -0xd0(%rbp), %rsi
callq 0x50c0
jmp 0x7baa
leaq 0x2b613(%rip), %rdx     # 0x331c4
leaq -0xf0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x63d0
jmp 0x7bc6
leaq -0x98(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x5520
jmp 0x7bdb
leaq -0xf0(%rbp), %rdi
callq 0x52b0
movq 0x443f2(%rip), %rdi     # 0x4bfe0
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x5740
movb %al, -0x5f9(%rbp)
jmp 0x7c05
movb -0x5f9(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x7b95
leaq -0xd0(%rbp), %rdi
callq 0x52b0
jmp 0x7e19
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x7c54
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x52b0
leaq -0xd0(%rbp), %rdi
callq 0x52b0
jmp 0x81a5
leaq -0x2f8(%rbp), %rdi
leaq -0x58(%rbp), %rsi
movl $0x8, %edx
callq 0x5640
jmp 0x7c7c
leaq -0x2f8(%rbp), %rdi
callq 0x5630
movb %al, -0x5fa(%rbp)
jmp 0x7c90
movb -0x5fa(%rbp), %al
testb $0x1, %al
jne 0x7c9f
jmp 0x7d9f
leaq -0x318(%rbp), %rdi
callq 0x5570
leaq -0x2f8(%rbp), %rdi
leaq -0x318(%rbp), %rsi
callq 0x50c0
jmp 0x7cc0
leaq 0x2b4fd(%rip), %rdx     # 0x331c4
leaq -0x338(%rbp), %rdi
leaq -0x318(%rbp), %rsi
callq 0x63d0
jmp 0x7cdc
leaq -0x98(%rbp), %rdi
leaq -0x338(%rbp), %rsi
callq 0x5520
jmp 0x7cf1
leaq -0x338(%rbp), %rdi
callq 0x52b0
movq -0x2f8(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x2f8(%rbp,%rax), %rdi
callq 0x5740
movb %al, -0x5fb(%rbp)
jmp 0x7d1d
movb -0x5fb(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x7cab
leaq -0x2f8(%rbp), %rdi
callq 0x50d0
jmp 0x7d37
leaq -0x318(%rbp), %rdi
callq 0x52b0
jmp 0x7dd3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x7e08
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x7d91
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0x338(%rbp), %rdi
callq 0x52b0
leaq -0x318(%rbp), %rdi
callq 0x52b0
jmp 0x7e08
leaq -0x78(%rbp), %rdi
callq 0x51b0
movq %rax, %rsi
leaq 0x2b3f3(%rip), %rdi     # 0x331a5
xorl %eax, %eax
callq 0x5070
jmp 0x7dbb
leaq 0x2b3b2(%rip), %rdi     # 0x33174
callq 0x5390
jmp 0x7dc9
movl $0x3, %edi
callq 0x54e0
testb $0x1, -0x99(%rbp)
je 0x7dfa
leaq -0x58(%rbp), %rdi
callq 0x51b0
movq %rax, %rsi
leaq 0x2b3a4(%rip), %rdi     # 0x33193
xorl %eax, %eax
callq 0x5070
jmp 0x7df8
jmp 0x7dfa
leaq -0x2f8(%rbp), %rdi
callq 0x5100
jmp 0x7e19
leaq -0x2f8(%rbp), %rdi
callq 0x5100
jmp 0x81a5
movl $0x78, %edi
callq 0x5400
movq %rax, -0x608(%rbp)
jmp 0x7e2c
movb $0x1, -0x381(%rbp)
leaq -0x380(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x51d0
jmp 0x7e48
leaq -0x360(%rbp), %rdi
leaq -0x380(%rbp), %rsi
callq 0x81e0
jmp 0x7e5d
movq -0x608(%rbp), %rdi
leaq -0x360(%rbp), %rsi
callq 0x71c0
jmp 0x7e72
movb $0x0, -0x381(%rbp)
leaq -0x360(%rbp), %rdi
callq 0x52b0
leaq -0x380(%rbp), %rdi
callq 0x52b0
movq -0x608(%rbp), %rax
movq %rax, -0x340(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x5690
testb $0x1, %al
jne 0x7f4e
testb $0x1, -0x99(%rbp)
je 0x7f4e
leaq -0x38(%rbp), %rdi
callq 0x51b0
movq %rax, %rsi
leaq 0x2b2ce(%rip), %rdi     # 0x3319e
xorl %eax, %eax
callq 0x5070
jmp 0x7ed9
jmp 0x7f4e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x7f2d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x7f21
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0x360(%rbp), %rdi
callq 0x52b0
leaq -0x380(%rbp), %rdi
callq 0x52b0
testb $0x1, -0x381(%rbp)
jne 0x7f38
jmp 0x7f49
movq -0x608(%rbp), %rdi
movl $0x78, %esi
callq 0x5410
jmp 0x81a5
movq 0x44063(%rip), %rax     # 0x4bfb8
movl (%rax), %eax
cmpl -0x8(%rbp), %eax
jge 0x8121
movq -0x10(%rbp), %rax
movq 0x4404d(%rip), %rcx     # 0x4bfb8
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x618(%rbp)
leaq -0x3a9(%rbp), %rdi
movq %rdi, -0x610(%rbp)
callq 0x5710
movq -0x618(%rbp), %rsi
movq -0x610(%rbp), %rdx
leaq -0x3a8(%rbp), %rdi
callq 0x61c0
jmp 0x7fa8
leaq -0x78(%rbp), %rdi
leaq -0x3a8(%rbp), %rsi
callq 0x54f0
leaq -0x3a8(%rbp), %rdi
callq 0x52b0
leaq -0x3a9(%rbp), %rdi
callq 0x5460
testb $0x1, -0x99(%rbp)
je 0x801a
leaq -0x78(%rbp), %rdi
callq 0x51b0
movq %rax, %rsi
leaq 0x2b1bd(%rip), %rdi     # 0x331a9
xorl %eax, %eax
callq 0x5070
jmp 0x7ff5
jmp 0x801a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0x3a9(%rbp), %rdi
callq 0x5460
jmp 0x81a5
leaq -0x5b0(%rbp), %rdi
leaq -0x78(%rbp), %rsi
movl $0x10, %edx
callq 0x5790
jmp 0x8031
leaq -0x5b0(%rbp), %rdi
callq 0x5350
movb %al, -0x619(%rbp)
jmp 0x8045
movb -0x619(%rbp), %al
testb $0x1, %al
jne 0x8051
jmp 0x80cb
movq -0x340(%rbp), %rsi
leaq -0x5d0(%rbp), %rdi
callq 0x5bd0
jmp 0x8066
leaq -0x5b0(%rbp), %rdi
leaq -0x5d0(%rbp), %rsi
callq 0x53d0
jmp 0x807b
leaq -0x5d0(%rbp), %rdi
callq 0x52b0
leaq -0x5b0(%rbp), %rdi
callq 0x55a0
jmp 0x8095
jmp 0x80ff
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x8110
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0x5d0(%rbp), %rdi
callq 0x52b0
jmp 0x8110
leaq -0x78(%rbp), %rdi
callq 0x51b0
movq %rax, %rsi
leaq 0x2b0c7(%rip), %rdi     # 0x331a5
xorl %eax, %eax
callq 0x5070
jmp 0x80e7
leaq 0x2b086(%rip), %rdi     # 0x33174
callq 0x5390
jmp 0x80f5
movl $0x3, %edi
callq 0x54e0
leaq -0x5b0(%rbp), %rdi
callq 0x55d0
jmp 0x819e
leaq -0x5b0(%rbp), %rdi
callq 0x55d0
jmp 0x81a5
testb $0x1, -0x99(%rbp)
je 0x813c
leaq 0x2b084(%rip), %rdi     # 0x331b5
xorl %eax, %eax
callq 0x5070
jmp 0x813a
jmp 0x813c
movq -0x340(%rbp), %rsi
leaq -0x5f0(%rbp), %rdi
callq 0x5bd0
jmp 0x8151
leaq -0x5f0(%rbp), %rdi
callq 0x51b0
movq %rax, %rsi
leaq 0x2b03e(%rip), %rdi     # 0x331a5
xorl %eax, %eax
callq 0x5070
jmp 0x8170
leaq -0x5f0(%rbp), %rdi
callq 0x52b0
jmp 0x819e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0x5f0(%rbp), %rdi
callq 0x52b0
jmp 0x81a5
xorl %edi, %edi
callq 0x54e0
leaq -0x98(%rbp), %rdi
callq 0x52b0
leaq -0x78(%rbp), %rdi
callq 0x52b0
leaq -0x58(%rbp), %rdi
callq 0x52b0
leaq -0x38(%rbp), %rdi
callq 0x52b0
movq -0xa8(%rbp), %rdi
callq 0x5700
nopl (%rax,%rax)