/* autogenerated file */
# ifndef _GNU_SOURCE
#  define _GNU_SOURCE
# endif
#include <string.h>
#include <read-file.h>
#include "oci_image_index_spec.h"

oci_image_index_manifests_platform *make_oci_image_index_manifests_platform (yajl_val tree, struct parser_context *ctx, parser_error *err) {
    oci_image_index_manifests_platform *ret = NULL;
    *err = 0;
    (void) ctx;  /* Silence compiler warning.  */
    if (tree == NULL)
        return ret;
    ret = safe_malloc (sizeof (*ret));
    {
        yajl_val val = get_val (tree, "architecture", yajl_t_string);
        if (val) {
            char *str = YAJL_GET_STRING (val);
            ret->architecture = strdup (str ? str : "");
            if (ret->architecture == NULL)
                abort ();
        }
    }
    {
        yajl_val val = get_val (tree, "os", yajl_t_string);
        if (val) {
            char *str = YAJL_GET_STRING (val);
            ret->os = strdup (str ? str : "");
            if (ret->os == NULL)
                abort ();
        }
    }
    {
        yajl_val val = get_val (tree, "os.version", yajl_t_string);
        if (val) {
            char *str = YAJL_GET_STRING (val);
            ret->os_version = strdup (str ? str : "");
            if (ret->os_version == NULL)
                abort ();
        }
    }
    {
        yajl_val tmp = get_val (tree, "os.features", yajl_t_array);
        if (tmp && YAJL_GET_ARRAY (tmp)) {
            size_t i;
            yajl_val *values = YAJL_GET_ARRAY (tmp)->values;
            size_t len = YAJL_GET_ARRAY (tmp)->len;
            ret->os_features_len = len;
            ret->os_features = safe_malloc ((len + 1) * sizeof (*ret->os_features));
            for (i = 0; i < len; i++) {
                yajl_val val = values[i];
                if (val) {
                    char *str = YAJL_GET_STRING (val);
                    ret->os_features[i] = strdup (str ? str : "");
                    if (ret->os_features[i] == NULL)
                        abort ();
                }
            }
        }
    }
    {
        yajl_val val = get_val (tree, "variant", yajl_t_string);
        if (val) {
            char *str = YAJL_GET_STRING (val);
            ret->variant = strdup (str ? str : "");
            if (ret->variant == NULL)
                abort ();
        }
    }
    if (ret->architecture == NULL) {
        if (asprintf (err, "Required field '%s' not present", "architecture") < 0)
            abort();
        free_oci_image_index_manifests_platform (ret);
        return NULL;
    }
    if (ret->os == NULL) {
        if (asprintf (err, "Required field '%s' not present", "os") < 0)
            abort();
        free_oci_image_index_manifests_platform (ret);
        return NULL;
    }

    if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) {
        size_t i;
        for (i = 0; i < tree->u.object.len; i++)
            if (strcmp (tree->u.object.keys[i], "architecture") &&
                strcmp (tree->u.object.keys[i], "os") &&
                strcmp (tree->u.object.keys[i], "os.version") &&
                strcmp (tree->u.object.keys[i], "os.features") &&
                strcmp (tree->u.object.keys[i], "variant")) {
                fprintf (ctx->errfile, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]);
            }
        }
    return ret;
}

void free_oci_image_index_manifests_platform (oci_image_index_manifests_platform *ptr) {
    if (!ptr)
        return;
    free (ptr->architecture);
    ptr->architecture = NULL;
    free (ptr->os);
    ptr->os = NULL;
    free (ptr->os_version);
    ptr->os_version = NULL;
    if (ptr->os_features) {
        size_t i;
        for (i = 0; i < ptr->os_features_len; i++) {
            if (ptr->os_features[i]) {
                free (ptr->os_features[i]);
                ptr->os_features[i] = NULL;
            }
        }
        free (ptr->os_features);
        ptr->os_features = NULL;
    }
    free (ptr->variant);
    ptr->variant = NULL;
    free (ptr);
}

bool gen_oci_image_index_manifests_platform (yajl_gen g, oci_image_index_manifests_platform *ptr, struct parser_context *ctx, parser_error *err) {
    bool stat = true;
    *err = 0;
    (void) ptr;  /* Silence compiler warning.  */
    (void) ctx;  /* Silence compiler warning.  */
    stat = reformat_start_map (g);
    if (!stat)
        return false;
    if (ptr->architecture) {
        stat = reformat_map_key (g, (unsigned char *) "architecture", 12 /* strlen ("architecture") */);
        if (!stat)
            return false;
        stat = reformat_string (g, (unsigned char *) ptr->architecture, strlen (ptr->architecture));
        if (!stat)
            return false;
    }
    if (ptr->os) {
        stat = reformat_map_key (g, (unsigned char *) "os", 2 /* strlen ("os") */);
        if (!stat)
            return false;
        stat = reformat_string (g, (unsigned char *) ptr->os, strlen (ptr->os));
        if (!stat)
            return false;
    }
    if (ptr->os_version) {
        stat = reformat_map_key (g, (unsigned char *) "os.version", 10 /* strlen ("os.version") */);
        if (!stat)
            return false;
        stat = reformat_string (g, (unsigned char *) ptr->os_version, strlen (ptr->os_version));
        if (!stat)
            return false;
    }
    if (ptr->os_features) {
        stat = reformat_map_key (g, (unsigned char *) "os.features", 11 /* strlen ("os.features") */);
        if (!stat)
            return false;
        size_t i;
        stat = reformat_start_array (g);
        if (!stat)
            return false;
        for (i = 0; i < ptr->os_features_len; i++) {
            stat = reformat_string (g, (unsigned char *) ptr->os_features[i], strlen (ptr->os_features[i]));
            if (!stat)
                return false;
        }
        stat = reformat_end_array (g);
        if (!stat)
            return false;
    }
    if (ptr->variant) {
        stat = reformat_map_key (g, (unsigned char *) "variant", 7 /* strlen ("variant") */);
        if (!stat)
            return false;
        stat = reformat_string (g, (unsigned char *) ptr->variant, strlen (ptr->variant));
        if (!stat)
            return false;
    }
    stat = reformat_end_map (g);
    if (!stat)
        return false;
    return true;
}

void free_oci_image_index_manifests_annotations (oci_image_index_manifests_annotations *ptr) {
    if (!ptr)
        return;
    free_cells (ptr);
    ptr = NULL;
    free (ptr);
}

oci_image_index_manifests_element *make_oci_image_index_manifests_element (yajl_val tree, struct parser_context *ctx, parser_error *err) {
    oci_image_index_manifests_element *ret = NULL;
    *err = 0;
    (void) ctx;  /* Silence compiler warning.  */
    if (tree == NULL)
        return ret;
    ret = safe_malloc (sizeof (*ret));
    {
        yajl_val val = get_val (tree, "mediaType", yajl_t_string);
        if (val) {
            char *str = YAJL_GET_STRING (val);
            ret->media_type = strdup (str ? str : "");
            if (ret->media_type == NULL)
                abort ();
        }
    }
    {
        yajl_val val = get_val (tree, "size", yajl_t_number);
        if (val) {
            ret->size = strtoll (YAJL_GET_NUMBER (val), NULL, 10);
            ret->size_present = 1;
        }
    }
    {
        yajl_val val = get_val (tree, "digest", yajl_t_string);
        if (val) {
            char *str = YAJL_GET_STRING (val);
            ret->digest = strdup (str ? str : "");
            if (ret->digest == NULL)
                abort ();
        }
    }
    {
        yajl_val tmp = get_val (tree, "urls", yajl_t_array);
        if (tmp && YAJL_GET_ARRAY (tmp)) {
            size_t i;
            yajl_val *values = YAJL_GET_ARRAY (tmp)->values;
            size_t len = YAJL_GET_ARRAY (tmp)->len;
            ret->urls_len = len;
            ret->urls = safe_malloc ((len + 1) * sizeof (*ret->urls));
            for (i = 0; i < len; i++) {
                yajl_val val = values[i];
                if (val) {
                    char *str = YAJL_GET_STRING (val);
                    ret->urls[i] = strdup (str ? str : "");
                    if (ret->urls[i] == NULL)
                        abort ();
                }
            }
        }
    }
    ret->platform = make_oci_image_index_manifests_platform (get_val (tree, "platform", yajl_t_object), ctx, err);
    if (ret->platform == NULL && *err != 0) {
        free_oci_image_index_manifests_element (ret);
        return NULL;
    }
    {
        yajl_val tmp = get_val (tree, "annotations", yajl_t_object);
        if (tmp != NULL) {
            ret->annotations = read_map_string_string (tmp);
        }
    }
    if (ret->media_type == NULL) {
        if (asprintf (err, "Required field '%s' not present", "mediaType") < 0)
            abort();
        free_oci_image_index_manifests_element (ret);
        return NULL;
    }
    if (ret->digest == NULL) {
        if (asprintf (err, "Required field '%s' not present", "digest") < 0)
            abort();
        free_oci_image_index_manifests_element (ret);
        return NULL;
    }
    return ret;
}

void free_oci_image_index_manifests_element (oci_image_index_manifests_element *ptr) {
    if (!ptr)
        return;
    free (ptr->media_type);
    ptr->media_type = NULL;
    free (ptr->digest);
    ptr->digest = NULL;
    if (ptr->urls) {
        size_t i;
        for (i = 0; i < ptr->urls_len; i++) {
            if (ptr->urls[i]) {
                free (ptr->urls[i]);
                ptr->urls[i] = NULL;
            }
        }
        free (ptr->urls);
        ptr->urls = NULL;
    }
    if (ptr->platform) {
        free_oci_image_index_manifests_platform (ptr->platform);
        ptr->platform = NULL;
    }
    free_oci_image_index_manifests_annotations (ptr->annotations);
    ptr->annotations = NULL;
    free (ptr);
}

bool gen_oci_image_index_manifests_element (yajl_gen g, oci_image_index_manifests_element *ptr, struct parser_context *ctx, parser_error *err) {
    bool stat = true;
    *err = 0;
    (void) ptr;  /* Silence compiler warning.  */
    (void) ctx;  /* Silence compiler warning.  */
    stat = reformat_start_map (g);
    if (!stat)
        return false;
    if (ptr->media_type) {
        stat = reformat_map_key (g, (unsigned char *) "mediaType", 9 /* strlen ("mediaType") */);
        if (!stat)
            return false;
        stat = reformat_string (g, (unsigned char *) ptr->media_type, strlen (ptr->media_type));
        if (!stat)
            return false;
    }
    if (ptr->size_present) {
        stat = reformat_map_key (g, (unsigned char *)"size", 4 /* strlen ("size") */);
        if (!stat)
            return false;
        stat = reformat_integer (g, ptr->size);
        if (!stat)
            return false;
    }
    if (ptr->digest) {
        stat = reformat_map_key (g, (unsigned char *) "digest", 6 /* strlen ("digest") */);
        if (!stat)
            return false;
        stat = reformat_string (g, (unsigned char *) ptr->digest, strlen (ptr->digest));
        if (!stat)
            return false;
    }
    if (ptr->urls) {
        stat = reformat_map_key (g, (unsigned char *) "urls", 4 /* strlen ("urls") */);
        if (!stat)
            return false;
        size_t i;
        stat = reformat_start_array (g);
        if (!stat)
            return false;
        for (i = 0; i < ptr->urls_len; i++) {
            stat = reformat_string (g, (unsigned char *) ptr->urls[i], strlen (ptr->urls[i]));
            if (!stat)
                return false;
        }
        stat = reformat_end_array (g);
        if (!stat)
            return false;
    }
    if (ptr->platform) {
        stat = reformat_map_key (g, (unsigned char *) "platform", 8 /* strlen ("platform") */);
        if (!stat)
            return false;
        stat = gen_oci_image_index_manifests_platform (g, ptr->platform, ctx, err);
        if (!stat)
            return false;
    }
    if (ptr->annotations) {
        stat = reformat_map_key (g, (unsigned char *) "annotations", 11 /* strlen ("annotations") */);
        if (!stat)
            return false;
        stat = gen_map_string_string (g, ptr->annotations);
        if (!stat)
            return false;
    }
    stat = reformat_end_map (g);
    if (!stat)
        return false;
    return true;
}

void free_oci_image_index_annotations (oci_image_index_annotations *ptr) {
    if (!ptr)
        return;
    free_cells (ptr);
    ptr = NULL;
    free (ptr);
}

oci_image_index *make_oci_image_index (yajl_val tree, struct parser_context *ctx, parser_error *err) {
    oci_image_index *ret = NULL;
    *err = 0;
    (void) ctx;  /* Silence compiler warning.  */
    if (tree == NULL)
        return ret;
    ret = safe_malloc (sizeof (*ret));
    {
        yajl_val val = get_val (tree, "schemaVersion", yajl_t_number);
        if (val) {
            ret->schema_version = strtoll (YAJL_GET_NUMBER (val), NULL, 10);
            ret->schema_version_present = 1;
        }
    }
    {
        yajl_val tmp = get_val (tree, "manifests", yajl_t_array);
        if (tmp && YAJL_GET_ARRAY (tmp)) {
            size_t i;
            yajl_val *values = YAJL_GET_ARRAY (tmp)->values;
            size_t len = YAJL_GET_ARRAY (tmp)->len;
            ret->manifests_len = len;
            ret->manifests = safe_malloc ((len + 1) * sizeof (*ret->manifests));
            for (i = 0; i < len; i++) {
                ret->manifests[i] = make_oci_image_index_manifests_element (values[i], ctx, err);
                if (ret->manifests[i] == NULL) {
                    free_oci_image_index (ret);
                    return NULL;
                }
            }
        }
    }
    {
        yajl_val tmp = get_val (tree, "annotations", yajl_t_object);
        if (tmp != NULL) {
            ret->annotations = read_map_string_string (tmp);
        }
    }
    if (ret->manifests == NULL) {
        if (asprintf (err, "Required field '%s' not present", "manifests") < 0)
            abort();
        free_oci_image_index (ret);
        return NULL;
    }

    if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) {
        size_t i;
        for (i = 0; i < tree->u.object.len; i++)
            if (strcmp (tree->u.object.keys[i], "schemaVersion") &&
                strcmp (tree->u.object.keys[i], "manifests") &&
                strcmp (tree->u.object.keys[i], "annotations")) {
                fprintf (ctx->errfile, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]);
            }
        }
    return ret;
}

void free_oci_image_index (oci_image_index *ptr) {
    if (!ptr)
        return;
    if (ptr->manifests) {
        size_t i;
        for (i = 0; i < ptr->manifests_len; i++)
            if (ptr->manifests[i]) {
                free_oci_image_index_manifests_element (ptr->manifests[i]);
                ptr->manifests[i] = NULL;
            }
        free (ptr->manifests);
        ptr->manifests = NULL;
    }
    free_oci_image_index_annotations (ptr->annotations);
    ptr->annotations = NULL;
    free (ptr);
}

bool gen_oci_image_index (yajl_gen g, oci_image_index *ptr, struct parser_context *ctx, parser_error *err) {
    bool stat = true;
    *err = 0;
    (void) ptr;  /* Silence compiler warning.  */
    (void) ctx;  /* Silence compiler warning.  */
    stat = reformat_start_map (g);
    if (!stat)
        return false;
    if (ptr->schema_version_present) {
        stat = reformat_map_key (g, (unsigned char *)"schemaVersion", 13 /* strlen ("schemaVersion") */);
        if (!stat)
            return false;
        stat = reformat_integer (g, ptr->schema_version);
        if (!stat)
            return false;
    }
    if (ptr->manifests) {
        stat = reformat_map_key (g, (unsigned char *) "manifests", 9 /* strlen ("manifests") */);
        if (!stat)
            return false;
        size_t i;
        stat = reformat_start_array (g);
        if (!stat)
            return false;
        for (i = 0; i < ptr->manifests_len; i++) {
            stat = gen_oci_image_index_manifests_element(g, ptr->manifests[i], ctx, err);
            if (!stat)
                return false;
        }
        stat = reformat_end_array (g);
        if (!stat)
            return false;
    }
    if (ptr->annotations) {
        stat = reformat_map_key (g, (unsigned char *) "annotations", 11 /* strlen ("annotations") */);
        if (!stat)
            return false;
        stat = gen_map_string_string (g, ptr->annotations);
        if (!stat)
            return false;
    }
    stat = reformat_end_map (g);
    if (!stat)
        return false;
    return true;
}


oci_image_index *oci_image_index_parse_file (const char *filename, struct parser_context *ctx, parser_error *err) {
    yajl_val tree;
    size_t filesize;

    if (!filename || !err)
        return NULL;
    *err = NULL;
    struct parser_context tmp_ctx;
    if (!ctx) {
       ctx = &tmp_ctx;
       memset (&tmp_ctx, 0, sizeof (tmp_ctx));
    }
    char *content = read_file (filename, &filesize);
    char errbuf[1024];
    if (content == NULL) {
        if (asprintf (err, "cannot read the file: %s", filename) < 0)
            abort ();
        return NULL;
    }
    tree = yajl_tree_parse (content, errbuf, sizeof (errbuf));
    free (content);
    if (tree == NULL) {
        if (asprintf (err, "cannot parse the file: %s", errbuf) < 0)
            abort ();
        return NULL;
    }

    oci_image_index *ptr = make_oci_image_index (tree, ctx, err);
    yajl_tree_free (tree);
    return ptr;
}

oci_image_index *oci_image_index_parse_file_stream (FILE *stream, struct parser_context *ctx, parser_error *err) {
    yajl_val tree;
    size_t filesize;

    if (!stream || !err)
        return NULL;
    *err = NULL;
    struct parser_context tmp_ctx;
    if (!ctx) {
       ctx = &tmp_ctx;
       memset (&tmp_ctx, 0, sizeof (tmp_ctx));
    }
    char *content = fread_file (stream, &filesize);
    char errbuf[1024];
    if (content == NULL) {
        *err = strdup ("cannot read the file");
        return NULL;
    }
    tree = yajl_tree_parse (content, errbuf, sizeof (errbuf));
    free (content);
    if (tree == NULL) {
        if (asprintf (err, "cannot parse the stream: %s", errbuf) < 0)
            abort ();
        return NULL;
    }

    oci_image_index *ptr = make_oci_image_index (tree, ctx, err);
    yajl_tree_free (tree);
    return ptr;
}

oci_image_index *oci_image_index_parse_data (const char *jsondata, struct parser_context *ctx, parser_error *err) {
    yajl_val tree;
    struct parser_context tmp_ctx;

    if (!jsondata || !err)
        return NULL;
    *err = NULL;
    if (!ctx) {
       ctx = &tmp_ctx;
       memset (&tmp_ctx, 0, sizeof (tmp_ctx));
    }
    char errbuf[1024];
    tree = yajl_tree_parse (jsondata, errbuf, sizeof (errbuf));
    if (tree == NULL) {
        if (asprintf (err, "cannot parse the data: %s", errbuf) < 0)
            abort ();
        return NULL;
    }
    oci_image_index *ptr = make_oci_image_index (tree, ctx, err);
    yajl_tree_free (tree);
    return ptr;
}
char *oci_image_index_generate_json (oci_image_index *ptr, struct parser_context *ctx, parser_error *err) {
    yajl_gen g = NULL;
    struct parser_context tmp_ctx;
    const unsigned char *gen_buf = NULL;
    char *json_buf = NULL;
    size_t gen_len = 0;

    if (!ptr || !err)
        return NULL;
    *err = NULL;
    if (!ctx) {
        ctx = &tmp_ctx;
        memset (&tmp_ctx, 0, sizeof (tmp_ctx));
    }

    if (!json_gen_init (&g)) {
        *err = strdup ("Json_gen init failed");
        goto out;
    }
    if (!gen_oci_image_index (g, ptr, ctx, err)) {
        *err = strdup ("Failed to generate json");
        goto free_out;
    }

    yajl_gen_get_buf (g, &gen_buf, &gen_len);
    if (!gen_buf) {
        *err = strdup ("Error to get generated json");
        goto free_out;
    }

    json_buf = safe_malloc (gen_len + 1);
    memcpy (json_buf, gen_buf, gen_len);
    json_buf[gen_len] = '\0';

free_out:
    yajl_gen_clear (g);
    yajl_gen_free (g);
out:
    return json_buf;
}
