/* CS107 Realloc Example
 * Code by Nick Troccoli
 * 
 * This program prints out a string containing a random number
 * (0 or more) of lowercase letters.  It demonstrates using realloc
 * by growing the string over time as we generate more characters,
 * stopping once we generate a null terminator.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <time.h>       // for random number generation
#include <stdlib.h>     // for random number generation


/* This function returns a random letter that is
 * either lowercase, or the null terminator.
 */
const char *letters = "abcdefghijklmnopqrstuvwxyz";
char getRandomCharacter() {
    // generate a random index from 0-26, inclusive (including null terminator option)
    int randomIndex = rand() % (strlen(letters) + 1);
    return letters[randomIndex];
}

/* This function returns a string containing a random number (0 or more)
 * of lowercase letters.  The returned string is heap-allocated, and it
 * is the caller's responsibility to free it.
 */
char *generateRandomString() {
    // We always read at least one character
    char *buf = malloc(sizeof(char));
    assert(buf != NULL);
    buf[0] = getRandomCharacter();
    int buflen = 1;

    // While we haven't seen a null terminator, keep going
    while (buf[buflen - 1] != '\0') {
        // make space for an additional character and add it
        buf = realloc(buf, buflen + 1);
        assert(buf != NULL);
        buflen++;
        buf[buflen - 1] = getRandomCharacter();
    }

    return buf;
}

int main(int argc, char const *argv[]) {
    // Random number initialization
    srand(time(NULL));

    char *str = generateRandomString();
    printf("%s\n", str);
    free(str);

    return 0;
}
