/**
 * Copyright © 2019, Oracle and/or its affiliates. All rights reserved.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl
 *
 */
#include "vector-of-strings.h"
#include "malloc.h"
#include <assert.h>
#include <string.h>

struct vector_of_strings {
    size_t n;
    size_t size;
    char **strings;
};

struct vector_of_strings *
mk_vector_of_strings(void) {
    struct vector_of_strings *MALLOC(v);
    *v = (struct vector_of_strings){0, 2, NULL};
    MALLOC_N(v->strings, v->size);
    return v;
}

struct vector_of_strings *
vector_of_strings_destroy(struct vector_of_strings *v) {
    for (size_t i = 0; i < v->n; i++) {
        FREE(v->strings[i]);
    }
    FREE(v->strings);
    FREE(v);
    return NULL;
}

char*
vector_of_strings_pop(struct vector_of_strings *v) {
    if (v->n == 0) return NULL;
    return v->strings[-- v->n];
}

void
vector_of_strings_push(struct vector_of_strings *v, const char *string) {
    if (v->n >= v->size) {
        assert(v->size);
        v->size *= 2;
        REALLOC(v->strings, v->size);
    }
    assert(v->n < v->size);
    v->strings[v->n++] = strdup(string);
}

size_t
vector_of_strings_size(const struct vector_of_strings *v) {
    return v->n;
}

int
vector_of_strings_any(const struct vector_of_strings *v,
                      int (*predicate)(const char *string, void *extra),
                      void *extra) {
    for (size_t i = 0; i < v->n; i++) {
        int r = predicate(v->strings[i], extra);
        if (r) return r;
    }
    return 0;
}

char const *
vector_of_strings_fetch(const struct vector_of_strings *v, size_t idx) {
    assert(idx < vector_of_strings_size(v));
    return v->strings[idx];
}
