// File: /workspace/github_cpp_makefile_star2_O2/maclellant[P]ReliableGoBackN/server.cpp
// Function: gremlin(char*, int, int, int)
int gremlin(char *data, int corrupt_chance, int loss_chance, int delay_chance)
{
    if (corrupt_chance < 0)
        corrupt_chance = 0;
    if (corrupt_chance > 100)
        corrupt_chance = 100;
    if (loss_chance < 0)
        loss_chance = 0;
    if (loss_chance > 100)
        loss_chance = 100;
    if (delay_chance < 0)
        delay_chance = 0;
    if (delay_chance > 100)
        delay_chance = 100;
    int corrupt_roll = rand() % 101;
    int loss_roll = rand() % 101;
    int delay_roll = rand() % 101;
    if (loss_roll <= loss_chance) 
    {
        return LOST;
    }
    if (corrupt_roll <= corrupt_chance)
    {
        int num_corrupt = rand() % 101;
        if (num_corrupt <= 70)
        {
            int corrupt_byte = rand() % (PACKET_SIZE - HEADER_SIZE);
            data[corrupt_byte] = ~data[corrupt_byte];
        }
        else if (num_corrupt <= 90)
        {
            int corrupt_byte = rand() % (PACKET_SIZE - HEADER_SIZE);
            data[corrupt_byte] = ~data[corrupt_byte];

            int prev_corrupt = corrupt_byte;
            while (prev_corrupt == corrupt_byte)
            {
                corrupt_byte = rand() % (PACKET_SIZE - HEADER_SIZE);
            }
            data[corrupt_byte] = ~data[corrupt_byte];
        }
        else
        {
            int corrupt_byte = rand() % (PACKET_SIZE - HEADER_SIZE);
            data[corrupt_byte] = ~data[corrupt_byte];

            int prev_corrupt1 = corrupt_byte;
            while (prev_corrupt1 == corrupt_byte)
            {
                corrupt_byte = rand() % (PACKET_SIZE - HEADER_SIZE);
            }
            data[corrupt_byte] = ~data[corrupt_byte];

            int prev_corrupt2 = corrupt_byte;
            while (prev_corrupt1 == corrupt_byte
                || prev_corrupt2 == corrupt_byte)
            {
                corrupt_byte = rand() % (PACKET_SIZE - HEADER_SIZE);
            }
            data[corrupt_byte] = ~data[corrupt_byte];
        }
    }
    if (delay_roll <= delay_chance)
    {
        return DELAYED;
    }
    return FINE;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %edx, %r13d
xorl %r12d, %r12d
testl %edx, %edx
cmovlel %r12d, %r13d
pushq $0x64
popq %r14
cmpl %r14d, %r13d
cmovgel %r14d, %r13d
movl %esi, -0x2c(%rbp)
testl %ecx, %ecx
cmovlel %r12d, %ecx
movq %rdi, -0x38(%rbp)
cmpl %r14d, %ecx
cmovgel %r14d, %ecx
movl %ecx, -0x40(%rbp)
callq 0x2080
movl %eax, -0x3c(%rbp)
callq 0x2080
pushq $0x65
popq %rbx
cltd
idivl %ebx
movl %edx, %r15d
callq 0x2080
cltd
idivl %ebx
cmpl %r13d, %r15d
jle 0x30ef
movl %edx, %ecx
movl -0x3c(%rbp), %eax
cltd
idivl %ebx
movl -0x2c(%rbp), %eax
testl %eax, %eax
cmovgl %eax, %r12d
cmpl $0x64, %r12d
cmovll %r12d, %r14d
cmpl %r14d, %edx
jg 0x30e3
movl %ecx, -0x2c(%rbp)
callq 0x2080
cltd
idivl %ebx
cmpl $0x46, %edx
jg 0x3101
callq 0x2080
movl $0x1fa, %ecx            # imm = 0x1FA
cltd
idivl %ecx
movslq %edx, %rax
movq -0x38(%rbp), %rcx
notb (%rcx,%rax)
movl -0x2c(%rbp), %ecx
xorl %eax, %eax
cmpl -0x40(%rbp), %ecx
setle %al
addl %eax, %eax
jmp 0x30f2
pushq $0x1
popq %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %edx, %r14d
callq 0x2080
movl $0x1fa, %r15d           # imm = 0x1FA
cltd
idivl %r15d
movl %edx, %r12d
movslq %edx, %rax
movq -0x38(%rbp), %rcx
notb (%rcx,%rax)
cmpl $0x5b, %r14d
jae 0x3139
movl %r12d, %edx
cmpl %edx, %r12d
jne 0x30d6
callq 0x2080
cltd
idivl %r15d
jmp 0x3129
movl %r12d, %r13d
cmpl %r13d, %r12d
jne 0x314f
callq 0x2080
cltd
idivl %r15d
movl %edx, %r13d
jmp 0x313c
movslq %r13d, %rax
movq -0x38(%rbp), %rcx
notb (%rcx,%rax)
movl $0x1fa, %r14d           # imm = 0x1FA
movl %r13d, %edx
cmpl %edx, %r12d
setne %al
cmpl %edx, %r13d
setne %cl
testb %cl, %al
jne 0x30d6
callq 0x2080
cltd
idivl %r14d
jmp 0x3162