// File: /workspace/github_c_makefile_star2_O0/teodorst[P]app-huffman/huffman_serial.c
// Function: huffman_compress
int huffman_compress(char* input_filename, char* output_filename, char* codification_filename) {
    char** codification = (char**) calloc(128, sizeof(char*));

    FILE* input_fp = open_file(input_filename, "r");
    FILE* codification_fp = open_file(codification_filename, "w");
    FILE* output_fp = open_file(output_filename, "w");

    // compute input file size
    fseek(input_fp, 0, SEEK_END);
    unsigned long long int size = ftell(input_fp);
    fseek(input_fp, 0, SEEK_SET);

    int i;
    char *input_file_buffer = (char*) malloc(size);
    char *output_file_buffer = (char*) malloc(size);

    // read input file //
    fread(input_file_buffer, 1, size, input_fp);

    unsigned long long int *frequency = (unsigned long long int*) calloc(128, sizeof(unsigned long long int));

    // compute frequency
    for (i = 0; i < size; i ++) {
        frequency[(unsigned char)input_file_buffer[i]] ++;
    }
    // create huffman_tree
    node_t* root_holder = build_huffman_tree(frequency);
    char path[MAX_BITS_CODE];
    find_codification(root_holder, path, 0, codification);

    int output_buffer_contor = 0;
    char output_char = 0;
    int contor = 7;
    unsigned long long int bits = 0;

    // time_t start = time(NULL);

    write_codification_for_chunk(input_file_buffer, size, codification, output_file_buffer, &output_buffer_contor, &output_char, &contor, &bits);

    // printf("%.2f\n", (double)(time(NULL) - start));

    fwrite(output_file_buffer, 1, output_buffer_contor, output_fp);
    if (output_char != 0) {
        fwrite(&output_char, 1, 1, output_fp);
    }

    write_metadata_file_serial(codification_fp, codification, bits);

	fclose(input_fp);
	fclose(output_fp);
    fclose(codification_fp);

    free_codification_matrix(codification);
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl $0x80, %edi
movl $0x8, %esi
callq 0x10b0
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
leaq 0x1c9f(%rip), %rsi      # 0x3004
callq 0x1290
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rdi
leaq 0x1c8d(%rip), %rsi      # 0x3006
callq 0x1290
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x1c79(%rip), %rsi      # 0x3006
callq 0x1290
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0x1110
movq -0x28(%rbp), %rdi
callq 0x10e0
movq %rax, -0x40(%rbp)
movq -0x28(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x1110
movq -0x40(%rbp), %rdi
callq 0x10f0
movq %rax, -0x50(%rbp)
movq -0x40(%rbp), %rdi
callq 0x10f0
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rdi
movq -0x40(%rbp), %rdx
movq -0x28(%rbp), %rcx
movl $0x1, %esi
callq 0x1050
movl $0x80, %edi
movl $0x8, %esi
callq 0x10b0
movq %rax, -0x60(%rbp)
movl $0x0, -0x44(%rbp)
movslq -0x44(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x143f
movq -0x60(%rbp), %rax
movq -0x50(%rbp), %rcx
movslq -0x44(%rbp), %rdx
movzbl (%rcx,%rdx), %ecx
movq (%rax,%rcx,8), %rdx
addq $0x1, %rdx
movq %rdx, (%rax,%rcx,8)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x140e
movq -0x60(%rbp), %rdi
callq 0x2c40
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
movq -0x20(%rbp), %rcx
xorl %edx, %edx
callq 0x2990
movl $0x0, -0xf4(%rbp)
movb $0x0, -0xf5(%rbp)
movl $0x7, -0xfc(%rbp)
movq $0x0, -0x108(%rbp)
movq -0x50(%rbp), %rdi
movq -0x40(%rbp), %rax
movl %eax, %esi
movq -0x20(%rbp), %rdx
movq -0x58(%rbp), %rcx
leaq -0xf4(%rbp), %r8
leaq -0xf5(%rbp), %r9
leaq -0xfc(%rbp), %r10
leaq -0x108(%rbp), %rax
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x2200
movq -0x58(%rbp), %rdi
movslq -0xf4(%rbp), %rdx
movq -0x38(%rbp), %rcx
movl $0x1, %esi
callq 0x1170
movsbl -0xf5(%rbp), %eax
cmpl $0x0, %eax
je 0x1501
movq -0x38(%rbp), %rcx
leaq -0xf5(%rbp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x1170
movq -0x30(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x108(%rbp), %rdx
callq 0x2470
movq -0x28(%rbp), %rdi
callq 0x1060
movq -0x38(%rbp), %rdi
callq 0x1060
movq -0x30(%rbp), %rdi
callq 0x1060
movq -0x20(%rbp), %rdi
callq 0x12d0
xorl %eax, %eax
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
nopw %cs:(%rax,%rax)