#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "numbers.h"
#include "bintree.h"

//TODO: getDuplicate und createNumbers implementieren
/*  *   * Erzeugen eines Arrays mit der vom Nutzer eingegebenen Anzahl an Zufallszahlen.
  * Sicherstellen, dass beim Befüllen keine Duplikate entstehen.
  * Duplizieren eines zufälligen Eintrags im Array.
  * in `getDuplicate()`: Sortieren des Arrays und Erkennen der doppelten Zahl durch Vergleich benachbarter Elemente. */

// Returns len random numbers between 1 and 2x len in random order which are all different, except for two entries.
// Returns NULL on errors. Use your implementation of the binary search tree to check for possible duplicates while
// creating random numbers.
static int compare(const void *a, const void *b) 
{
    return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b);
}

unsigned int *createNumbers(unsigned int len)
{
    if (len < 2) 
        return NULL;

    unsigned int *numbers = malloc(sizeof(unsigned int) * len);

    if (!numbers) 
        return NULL;

    srand(time(NULL));

    TreeNode *root = NULL;

    unsigned int i = 0;
    while (i < len - 1) 
    {
        unsigned int val = (rand() % (2 * len)) + 1;
        int isDup = 0;

        root = addToTree(root, &val, sizeof(unsigned int), compare, &isDup);

        if (!isDup) 
        {
            numbers[i++] = val;
        }
    }

    // Duplicate one random entry
    unsigned int dupIndex = rand() % (len - 1);
    numbers[len - 1] = numbers[dupIndex];

    clearTree(root); //Notwendigkeit muss noch restlichem Code entnommen werden
    return numbers;
}

// Returns only the only number in numbers which is present twice. Returns zero on errors.
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
{
    if (!numbers || len < 2) 
        return 0;

    unsigned int *numbersCopy = malloc(sizeof(unsigned int) * len);
    if (!numbersCopy) 
        return 0;

    for (unsigned int i = 0; i < len; i++) 
    {
        numbersCopy[i] = numbers[i];
    }

    qsort(numbersCopy, len, sizeof(unsigned int), compare);

    unsigned int duplicate = 0;
    for (unsigned int i = 0; i < len - 1; i++) 
    {
        if (numbersCopy[i] == numbersCopy[i+1]) 
        {
            duplicate = numbersCopy[i];
            break;
        }
    }

    free(numbersCopy);
    return duplicate;
}
