#include "random_data.h"
#include <string.h>
#include <malloc_wrappers.h>
#include <pb_encode.h>

#ifndef LLVMFUZZER

static uint32_t g_random_seed = 1234;

void random_set_seed(uint32_t seed)
{
    g_random_seed = seed;
}

uint32_t random_get_seed()
{
    return g_random_seed;
}

/* Uses xorshift64 here instead of rand() for both speed and
 * reproducibility across platforms. */
uint32_t rand_word()
{
    g_random_seed ^= g_random_seed << 13;
    g_random_seed ^= g_random_seed >> 17;
    g_random_seed ^= g_random_seed << 5;
    return g_random_seed;
}

/* Get a random integer in range, with approximately flat distribution. */
int rand_int(int min, int max)
{
    return rand_word() % (max + 1 - min) + min;
}

bool rand_bool()
{
    return rand_word() & 1;
}

/* Get a random byte, with skewed distribution.
 * Important corner cases like 0xFF, 0x00 and 0xFE occur more
 * often than other values. */
uint8_t rand_byte()
{
    uint32_t w = rand_word();
    uint8_t b = w & 0xFF;
    if (w & 0x100000)
        b >>= (w >> 8) & 7;
    if (w & 0x200000)
        b <<= (w >> 12) & 7;
    if (w & 0x400000)
        b ^= 0xFF;
    return b;
}

/* Get a random length, with skewed distribution.
 * Favors the shorter lengths, but always at least 1. */
size_t rand_len(size_t max)
{
    uint32_t w = rand_word();
    size_t s;
    if (w & 0x800000)
        w &= 3;
    else if (w & 0x400000)
        w &= 15;
    else if (w & 0x200000)
        w &= 255;

    s = (w % max);
    if (s == 0)
        s = 1;

    return s;
}

/* Fills a buffer with random data with skewed distribution. */
void rand_fill(uint8_t *buf, size_t count)
{
    for (; count > 0; count--)
    {
        *buf++ = rand_byte();
    }
}

/* Fill with random protobuf-like data */
size_t rand_fill_protobuf(uint8_t *buf, size_t min_bytes, size_t max_bytes, int min_tag)
{
    pb_ostream_t stream = pb_ostream_from_buffer(buf, max_bytes);

    while(stream.bytes_written < min_bytes)
    {
        pb_wire_type_t wt = rand_int(0, 3);
        if (wt == 3) wt = 5; /* Gap in values */

        if (!pb_encode_tag(&stream, wt, rand_int(min_tag, min_tag + 512)))
            break;

        if (wt == PB_WT_VARINT)
        {
            uint64_t value;
            rand_fill((uint8_t*)&value, sizeof(value));
            pb_encode_varint(&stream, value);
        }
        else if (wt == PB_WT_64BIT)
        {
            uint64_t value;
            rand_fill((uint8_t*)&value, sizeof(value));
            pb_encode_fixed64(&stream, &value);
        }
        else if (wt == PB_WT_32BIT)
        {
            uint32_t value;
            rand_fill((uint8_t*)&value, sizeof(value));
            pb_encode_fixed32(&stream, &value);
        }
        else if (wt == PB_WT_STRING)
        {
            size_t len;
            uint8_t *buf;

            if (min_bytes > stream.bytes_written)
                len = rand_len(min_bytes - stream.bytes_written);
            else
                len = 0;

            buf = malloc(len);
            pb_encode_varint(&stream, len);
            rand_fill(buf, len);
            pb_write(&stream, buf, len);
            free(buf);
        }
    }

    return stream.bytes_written;
}

/* Given a buffer of data, mess it up a bit */
void rand_mess(uint8_t *buf, size_t count)
{
    int m = rand_int(0, 3);

    if (m == 0)
    {
        /* Replace random substring */
        int s = rand_int(0, count - 1);
        int l = rand_len(count - s);
        rand_fill(buf + s, l);
    }
    else if (m == 1)
    {
        /* Swap random bytes */
        int a = rand_int(0, count - 1);
        int b = rand_int(0, count - 1);
        int x = buf[a];
        buf[a] = buf[b];
        buf[b] = x;
    }
    else if (m == 2)
    {
        /* Duplicate substring */
        int s = rand_int(0, count - 2);
        int l = rand_len((count - s) / 2);
        memcpy(buf + s + l, buf + s, l);
    }
    else if (m == 3)
    {
        /* Add random protobuf noise */
        int s = rand_int(0, count - 1);
        int l = rand_len(count - s);
        rand_fill_protobuf(buf + s, l, count - s, 1);
    }
}

/* Append or prepend protobuf noise */
void rand_protobuf_noise(uint8_t *buffer, size_t bufsize, size_t *msglen)
{
    int m = rand_int(0, 2);
    size_t max_size = bufsize - 32 - *msglen;
    if (m == 1)
    {
        /* Prepend */
        uint8_t *tmp = malloc_with_check(bufsize);
        size_t s = rand_fill_protobuf(tmp, rand_len(max_size), bufsize - *msglen, 1000);
        memmove(buffer + s, buffer, *msglen);
        memcpy(buffer, tmp, s);
        free_with_check(tmp);
        *msglen += s;
    }
    else if (m == 2)
    {
        /* Append */
        size_t s = rand_fill_protobuf(buffer + *msglen, rand_len(max_size), bufsize - *msglen, 1000);
        *msglen += s;
    }
}

#endif
