// File: sbme-tutorials[P]huffman-encoding/main.cpp
// Function: main
int main(int argc, char *argv[])
{
    // To encode: ./a.exe -encode output_file_name < ./data/omaha.pgm
    Huffman H;
    int indexArgv = 1; // 0 is the exe
    if (indexArgv < argc && std::string(argv[indexArgv]) == "-encode")
    {
        indexArgv++;
        std::string encodedFileName;
        if (indexArgv < argc)
        {
            encodedFileName = std::string(argv[indexArgv]);
            H.encode(encodedFileName);
            indexArgv++;
        }
        else
        {
            encodedFileName = "output";
            H.encode(encodedFileName);
        }
    }
    else if (indexArgv < argc && std::string(argv[indexArgv]) == "-decode")
    {
        indexArgv++;
        std::string encodedFileName;
        std::string decodedFileName;
        if (indexArgv + 1 < argc)
        {
            encodedFileName = std::string(argv[indexArgv]);
            decodedFileName = std::string(argv[++indexArgv]);
            H.decode(encodedFileName, decodedFileName);
            indexArgv += 2;
        }
        else if (indexArgv < argc)
        {
            encodedFileName = std::string(argv[indexArgv]);
            H.decode(encodedFileName, encodedFileName);
            indexArgv++;
        }
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x410, %rsp            # imm = 0x410
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x3f40
movl $0x1, -0x13c(%rbp)
movl -0x13c(%rbp), %ecx
movl -0x8(%rbp), %edx
movb $0x0, -0x162(%rbp)
movb $0x0, -0x175(%rbp)
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x361(%rbp)
jge 0x376e
movq -0x10(%rbp), %rax
movslq -0x13c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x378(%rbp)
leaq -0x161(%rbp), %rdi
movq %rdi, -0x370(%rbp)
callq 0x34f0
movq -0x378(%rbp), %rsi
movq -0x370(%rbp), %rdx
movb $0x1, -0x162(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x40b0
jmp 0x373e
movb $0x1, -0x175(%rbp)
leaq 0x98b8(%rip), %rsi      # 0xd004
leaq -0x160(%rbp), %rdi
callq 0x4080
movb %al, -0x379(%rbp)
jmp 0x3760
movb -0x379(%rbp), %al
movb %al, -0x361(%rbp)
jmp 0x376e
movb -0x361(%rbp), %al
movb %al, -0x37a(%rbp)
testb $0x1, -0x175(%rbp)
jne 0x3785
jmp 0x3791
leaq -0x160(%rbp), %rdi
callq 0x31d0
testb $0x1, -0x162(%rbp)
jne 0x379c
jmp 0x37a8
leaq -0x161(%rbp), %rdi
callq 0x3310
movb -0x37a(%rbp), %al
testb $0x1, %al
jne 0x37b7
jmp 0x39ed
movl -0x13c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x13c(%rbp)
leaq -0x198(%rbp), %rdi
callq 0x33f0
movl -0x13c(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x395e
movq -0x10(%rbp), %rax
movslq -0x13c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x390(%rbp)
leaq -0x1b9(%rbp), %rdi
movq %rdi, -0x388(%rbp)
callq 0x34f0
movq -0x390(%rbp), %rsi
movq -0x388(%rbp), %rdx
leaq -0x1b8(%rbp), %rdi
callq 0x40b0
jmp 0x3826
leaq -0x198(%rbp), %rdi
movq %rdi, -0x398(%rbp)
leaq -0x1b8(%rbp), %rsi
movq %rsi, -0x3a0(%rbp)
callq 0x3360
movq -0x3a0(%rbp), %rdi
callq 0x31d0
leaq -0x1b9(%rbp), %rdi
callq 0x3310
movq -0x398(%rbp), %rsi
leaq -0x1e0(%rbp), %rdi
callq 0x3130
jmp 0x3874
leaq -0x138(%rbp), %rdi
leaq -0x1e0(%rbp), %rsi
callq 0x5730
jmp 0x3889
leaq -0x1e0(%rbp), %rdi
callq 0x31d0
movl -0x13c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x13c(%rbp)
jmp 0x39cb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
jmp 0x38e8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
testb $0x1, -0x175(%rbp)
jne 0x38da
jmp 0x38e6
leaq -0x160(%rbp), %rdi
callq 0x31d0
jmp 0x38e8
testb $0x1, -0x162(%rbp)
jne 0x38f3
jmp 0x38ff
leaq -0x161(%rbp), %rdi
callq 0x3310
jmp 0x3f27
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
leaq -0x1b9(%rbp), %rdi
callq 0x3310
jmp 0x39dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
jmp 0x39dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x31d0
jmp 0x39dc
leaq 0x96a7(%rip), %rsi      # 0xd00c
leaq -0x198(%rbp), %rdi
callq 0x33c0
jmp 0x3973
leaq -0x200(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0x3130
jmp 0x3988
leaq -0x138(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0x5730
jmp 0x399d
leaq -0x200(%rbp), %rdi
callq 0x31d0
jmp 0x39cb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
leaq -0x200(%rbp), %rdi
callq 0x31d0
jmp 0x39dc
leaq -0x198(%rbp), %rdi
callq 0x31d0
jmp 0x3f08
leaq -0x198(%rbp), %rdi
callq 0x31d0
jmp 0x3f27
movl -0x13c(%rbp), %ecx
movl -0x8(%rbp), %edx
movb $0x0, -0x222(%rbp)
movb $0x0, -0x223(%rbp)
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x3a1(%rbp)
jge 0x3a8c
movq -0x10(%rbp), %rax
movslq -0x13c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x3b8(%rbp)
leaq -0x221(%rbp), %rdi
movq %rdi, -0x3b0(%rbp)
callq 0x34f0
movq -0x3b8(%rbp), %rsi
movq -0x3b0(%rbp), %rdx
movb $0x1, -0x222(%rbp)
leaq -0x220(%rbp), %rdi
callq 0x40b0
jmp 0x3a5c
movb $0x1, -0x223(%rbp)
leaq 0x95a9(%rip), %rsi      # 0xd013
leaq -0x220(%rbp), %rdi
callq 0x4080
movb %al, -0x3b9(%rbp)
jmp 0x3a7e
movb -0x3b9(%rbp), %al
movb %al, -0x3a1(%rbp)
jmp 0x3a8c
movb -0x3a1(%rbp), %al
movb %al, -0x3ba(%rbp)
testb $0x1, -0x223(%rbp)
jne 0x3aa3
jmp 0x3aaf
leaq -0x220(%rbp), %rdi
callq 0x31d0
testb $0x1, -0x222(%rbp)
jne 0x3aba
jmp 0x3ac6
leaq -0x221(%rbp), %rdi
callq 0x3310
movb -0x3ba(%rbp), %al
testb $0x1, %al
jne 0x3ad5
jmp 0x3f06
movl -0x13c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x13c(%rbp)
leaq -0x248(%rbp), %rdi
callq 0x33f0
leaq -0x268(%rbp), %rdi
callq 0x33f0
movl -0x13c(%rbp), %eax
addl $0x1, %eax
cmpl -0x8(%rbp), %eax
jge 0x3d74
movq -0x10(%rbp), %rax
movslq -0x13c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x3d0(%rbp)
leaq -0x289(%rbp), %rdi
movq %rdi, -0x3c8(%rbp)
callq 0x34f0
movq -0x3d0(%rbp), %rsi
movq -0x3c8(%rbp), %rdx
leaq -0x288(%rbp), %rdi
callq 0x40b0
jmp 0x3b53
leaq -0x248(%rbp), %rdi
leaq -0x288(%rbp), %rsi
movq %rsi, -0x3e8(%rbp)
callq 0x3360
movq -0x3e8(%rbp), %rdi
callq 0x31d0
leaq -0x289(%rbp), %rdi
callq 0x3310
movq -0x10(%rbp), %rax
movslq -0x13c(%rbp), %rcx
movl %ecx, %edx
incl %edx
movl %edx, -0x13c(%rbp)
movq 0x8(%rax,%rcx,8), %rax
movq %rax, -0x3e0(%rbp)
leaq -0x2b1(%rbp), %rdi
movq %rdi, -0x3d8(%rbp)
callq 0x34f0
movq -0x3e0(%rbp), %rsi
movq -0x3d8(%rbp), %rdx
leaq -0x2b0(%rbp), %rdi
callq 0x40b0
jmp 0x3bd5
leaq -0x268(%rbp), %rdi
leaq -0x2b0(%rbp), %rsi
movq %rsi, -0x3f0(%rbp)
callq 0x3360
movq -0x3f0(%rbp), %rdi
callq 0x31d0
leaq -0x2b1(%rbp), %rdi
callq 0x3310
leaq -0x2d8(%rbp), %rdi
leaq -0x248(%rbp), %rsi
callq 0x3130
jmp 0x3c1c
leaq -0x2f8(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x3130
jmp 0x3c31
leaq -0x138(%rbp), %rdi
leaq -0x2d8(%rbp), %rsi
leaq -0x2f8(%rbp), %rdx
callq 0x6070
jmp 0x3c4d
leaq -0x2f8(%rbp), %rdi
callq 0x31d0
leaq -0x2d8(%rbp), %rdi
callq 0x31d0
movl -0x13c(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x13c(%rbp)
jmp 0x3ed2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
jmp 0x3cb8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
testb $0x1, -0x223(%rbp)
jne 0x3caa
jmp 0x3cb6
leaq -0x220(%rbp), %rdi
callq 0x31d0
jmp 0x3cb8
testb $0x1, -0x222(%rbp)
jne 0x3cc3
jmp 0x3ccf
leaq -0x221(%rbp), %rdi
callq 0x3310
jmp 0x3f27
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
leaq -0x289(%rbp), %rdi
callq 0x3310
jmp 0x3eec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
leaq -0x2b1(%rbp), %rdi
callq 0x3310
jmp 0x3eec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
jmp 0x3eec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
jmp 0x3d63
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
leaq -0x2f8(%rbp), %rdi
callq 0x31d0
leaq -0x2d8(%rbp), %rdi
callq 0x31d0
jmp 0x3eec
movl -0x13c(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x3ed0
movq -0x10(%rbp), %rax
movslq -0x13c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x400(%rbp)
leaq -0x319(%rbp), %rdi
movq %rdi, -0x3f8(%rbp)
callq 0x34f0
movq -0x400(%rbp), %rsi
movq -0x3f8(%rbp), %rdx
leaq -0x318(%rbp), %rdi
callq 0x40b0
jmp 0x3dc8
leaq -0x248(%rbp), %rdi
movq %rdi, -0x408(%rbp)
leaq -0x318(%rbp), %rsi
movq %rsi, -0x410(%rbp)
callq 0x3360
movq -0x410(%rbp), %rdi
callq 0x31d0
leaq -0x319(%rbp), %rdi
callq 0x3310
movq -0x408(%rbp), %rsi
leaq -0x340(%rbp), %rdi
callq 0x3130
jmp 0x3e16
leaq -0x360(%rbp), %rdi
leaq -0x248(%rbp), %rsi
callq 0x3130
jmp 0x3e2b
leaq -0x138(%rbp), %rdi
leaq -0x340(%rbp), %rsi
leaq -0x360(%rbp), %rdx
callq 0x6070
jmp 0x3e47
leaq -0x360(%rbp), %rdi
callq 0x31d0
leaq -0x340(%rbp), %rdi
callq 0x31d0
movl -0x13c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x13c(%rbp)
jmp 0x3ed0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
leaq -0x319(%rbp), %rdi
callq 0x3310
jmp 0x3eec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
jmp 0x3ec2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
leaq -0x360(%rbp), %rdi
callq 0x31d0
leaq -0x340(%rbp), %rdi
callq 0x31d0
jmp 0x3eec
jmp 0x3ed2
leaq -0x268(%rbp), %rdi
callq 0x31d0
leaq -0x248(%rbp), %rdi
callq 0x31d0
jmp 0x3f06
leaq -0x268(%rbp), %rdi
callq 0x31d0
leaq -0x248(%rbp), %rdi
callq 0x31d0
jmp 0x3f27
jmp 0x3f08
movl $0x0, -0x4(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x4160
movl -0x4(%rbp), %eax
addq $0x410, %rsp            # imm = 0x410
popq %rbp
retq
leaq -0x138(%rbp), %rdi
callq 0x4160
movq -0x170(%rbp), %rdi
callq 0x34e0
nop