// Generated from image-manifest-schema.json. Do not edit!
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <string.h>
#include <read-file.h>
#include "image_spec_schema_image_manifest_schema.h"

image_spec_schema_image_manifest_schema *
make_image_spec_schema_image_manifest_schema (yajl_val tree, const struct parser_context *ctx, parser_error *err)
{
    image_spec_schema_image_manifest_schema *ret = NULL;
    *err = NULL;
    (void) ctx;  /* Silence compiler warning.  */
    if (tree == NULL)
      return ret;
    ret = calloc (1, sizeof (*ret));
    if (ret == NULL)
      return NULL;
    do
      {
        yajl_val val = get_val (tree, "schemaVersion", yajl_t_number);
        if (val != NULL) {
            int invalid = common_safe_int (YAJL_GET_NUMBER (val), (int *)&ret->schema_version);
            if (invalid)
              {
                if (asprintf (err, "Invalid value '%s' with type 'integer' for key 'schemaVersion': %s", YAJL_GET_NUMBER (val), strerror (-invalid)) < 0)
                    *err = strdup ("error allocating memory");
                free_image_spec_schema_image_manifest_schema (ret);
                return NULL;
            }
            ret->schema_version_present = 1;
        }
      }
    while (0);
    ret->config = make_image_spec_schema_content_descriptor (get_val (tree, "config", yajl_t_object), ctx, err);
    if (ret->config == NULL && *err != 0)
      {
        free_image_spec_schema_image_manifest_schema (ret);
        return NULL;
      }
    do
      {
        yajl_val tmp = get_val (tree, "layers", yajl_t_array);
        if (tmp != NULL && YAJL_GET_ARRAY (tmp) != NULL && YAJL_GET_ARRAY (tmp)->len > 0)
          {
            size_t i;
            size_t len = YAJL_GET_ARRAY (tmp)->len;
            yajl_val *values = YAJL_GET_ARRAY (tmp)->values;
            ret->layers_len = len;
            ret->layers = calloc (len + 1, sizeof (*ret->layers));
            if (ret->layers == NULL)
              {
                free_image_spec_schema_image_manifest_schema (ret);
                return NULL;
              }
            for (i = 0; i < len; i++)
              {
                yajl_val val = values[i];
                ret->layers[i] = make_image_spec_schema_content_descriptor (val, ctx, err);
                if (ret->layers[i] == NULL)
                  {
                    free_image_spec_schema_image_manifest_schema (ret);
                    return NULL;
                }
            }
        }
      }
    while (0);
    do
      {
        yajl_val tmp = get_val (tree, "annotations", yajl_t_object);
        if (tmp != NULL)
          {
            ret->annotations = make_json_map_string_string (tmp, ctx, err);
            if (ret->annotations == NULL)
              {
                char *new_error = NULL;
                if (asprintf (&new_error, "Value error for key 'annotations': %s", *err ? *err : "null") < 0)
                  new_error = strdup ("error allocating memory");
                free (*err);
                *err = new_error;
                free_image_spec_schema_image_manifest_schema (ret);
                return NULL;
            }
        }
      }
    while (0);
    if (ret->config == NULL)
      {
        if (asprintf (err, "Required field '%s' not present",  "config") < 0)
            *err = strdup ("error allocating memory");
        free_image_spec_schema_image_manifest_schema (ret);
        return NULL;
      }
    if (ret->layers == NULL)
      {
        if (asprintf (err, "Required field '%s' not present",  "layers") < 0)
            *err = strdup ("error allocating memory");
        free_image_spec_schema_image_manifest_schema (ret);
        return NULL;
      }

    if (tree->type == yajl_t_object && (ctx->options & OPT_PARSE_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], "config")
                && strcmp (tree->u.object.keys[i], "layers")
                && strcmp (tree->u.object.keys[i], "annotations") && ctx->errfile != NULL)
              {
                (void) fprintf (ctx->errfile, "WARNING: unknown key found: %s\n",
                        tree->u.object.keys[i]);
              }
          }
      }
    return ret;
}

void
free_image_spec_schema_image_manifest_schema (image_spec_schema_image_manifest_schema *ptr)
{
    if (ptr == NULL)
        return;
    if (ptr->config != NULL)
      {
        free_image_spec_schema_content_descriptor (ptr->config);
        ptr->config = NULL;
      }
    if (ptr->layers != NULL)
      {
        size_t i;
        for (i = 0; i < ptr->layers_len; i++)
          if (ptr->layers[i] != NULL)
            {
              free_image_spec_schema_content_descriptor (ptr->layers[i]);
              ptr->layers[i] = NULL;
            }
        free (ptr->layers);
        ptr->layers = NULL;
      }
    free_json_map_string_string (ptr->annotations);
    ptr->annotations = NULL;
    free (ptr);
}

yajl_gen_status
gen_image_spec_schema_image_manifest_schema (yajl_gen g, const image_spec_schema_image_manifest_schema *ptr, const struct parser_context *ctx, parser_error *err)
{
    yajl_gen_status stat = yajl_gen_status_ok;
    *err = NULL;
    (void) ptr;  /* Silence compiler warning.  */
    stat = yajl_gen_map_open ((yajl_gen) g);
    if (stat != yajl_gen_status_ok)
        GEN_SET_ERROR_AND_RETURN (stat, err);
    if ((ctx->options & OPT_GEN_KEY_VALUE) || (ptr != NULL && ptr->schema_version_present))
      {
        long long int num = 0;
        stat = yajl_gen_string ((yajl_gen) g, (const unsigned char *)("schemaVersion"), 13 /* strlen ("schemaVersion") */);
        if (stat != yajl_gen_status_ok)
            GEN_SET_ERROR_AND_RETURN (stat, err);
        if (ptr != NULL && ptr->schema_version)
            num = (long long int)ptr->schema_version;
        stat = map_int (g, num);
        if (stat != yajl_gen_status_ok)
            GEN_SET_ERROR_AND_RETURN (stat, err);
      }
    if ((ctx->options & OPT_GEN_KEY_VALUE) || (ptr != NULL && ptr->config != NULL))
      {
        stat = yajl_gen_string ((yajl_gen) g, (const unsigned char *)("config"), 6 /* strlen ("config") */);
        if (stat != yajl_gen_status_ok)
            GEN_SET_ERROR_AND_RETURN (stat, err);
        stat = gen_image_spec_schema_content_descriptor (g, ptr != NULL ? ptr->config : NULL, ctx, err);
        if (stat != yajl_gen_status_ok)
            GEN_SET_ERROR_AND_RETURN (stat, err);
      }
    if ((ctx->options & OPT_GEN_KEY_VALUE) || (ptr != NULL && ptr->layers != NULL))
      {
        size_t len = 0, i;
        stat = yajl_gen_string ((yajl_gen) g, (const unsigned char *)("layers"), 6 /* strlen ("layers") */);
        if (stat != yajl_gen_status_ok)
            GEN_SET_ERROR_AND_RETURN (stat, err);
        if (ptr != NULL && ptr->layers != NULL)
            len = ptr->layers_len;
        if (!len && !(ctx->options & OPT_GEN_SIMPLIFY))
            yajl_gen_config (g, yajl_gen_beautify, 0);
        stat = yajl_gen_array_open ((yajl_gen) g);
        if (stat != yajl_gen_status_ok)
            GEN_SET_ERROR_AND_RETURN (stat, err);
        for (i = 0; i < len; i++)
          {
            stat = gen_image_spec_schema_content_descriptor (g, ptr->layers[i], ctx, err);
            if (stat != yajl_gen_status_ok)
                GEN_SET_ERROR_AND_RETURN (stat, err);
        }
        stat = yajl_gen_array_close ((yajl_gen) g);
        if (!len && !(ctx->options & OPT_GEN_SIMPLIFY))
            yajl_gen_config (g, yajl_gen_beautify, 1);
        if (stat != yajl_gen_status_ok)
            GEN_SET_ERROR_AND_RETURN (stat, err);
      }
    if ((ctx->options & OPT_GEN_KEY_VALUE) || (ptr != NULL && ptr->annotations != NULL))
      {
        stat = yajl_gen_string ((yajl_gen) g, (const unsigned char *)("annotations"), 11 /* strlen ("annotations") */);
        if (stat != yajl_gen_status_ok)
            GEN_SET_ERROR_AND_RETURN (stat, err);
        stat = gen_json_map_string_string (g, ptr ? ptr->annotations : NULL, ctx, err);
        if (stat != yajl_gen_status_ok)
            GEN_SET_ERROR_AND_RETURN (stat, err);
      }
    stat = yajl_gen_map_close ((yajl_gen) g);
    if (stat != yajl_gen_status_ok)
        GEN_SET_ERROR_AND_RETURN (stat, err);
    return yajl_gen_status_ok;
}


image_spec_schema_image_manifest_schema *image_spec_schema_image_manifest_schema_parse_file (const char *filename, const struct parser_context *ctx, parser_error *err) {
    image_spec_schema_image_manifest_schema *ptr = NULL;
    size_t filesize;
    char *content = NULL;

    if (filename == NULL || err == NULL)
      return NULL;

    *err = NULL;
    content = read_file (filename, &filesize);
    if (content == NULL)
      {
        if (asprintf (err, "cannot read the file: %s", filename) < 0)
            *err = strdup ("error allocating memory");
        return NULL;
      }
    ptr = image_spec_schema_image_manifest_schema_parse_data (content, ctx, err);
    free (content);
    return ptr;
}

image_spec_schema_image_manifest_schema *image_spec_schema_image_manifest_schema_parse_file_stream (FILE *stream, const struct parser_context *ctx, parser_error *err)
{
    image_spec_schema_image_manifest_schema *ptr = NULL;
    size_t filesize;
    char *content = NULL ;

    if (stream == NULL || err == NULL)
      return NULL;

    *err = NULL;
    content = fread_file (stream, &filesize);
    if (content == NULL)
      {
        *err = strdup ("cannot read the file");
        return NULL;
      }
    ptr = image_spec_schema_image_manifest_schema_parse_data (content, ctx, err);
    free (content);
    return ptr;
}

image_spec_schema_image_manifest_schema *image_spec_schema_image_manifest_schema_parse_data (const char *jsondata, const struct parser_context *ctx, parser_error *err)
{
    image_spec_schema_image_manifest_schema *ptr = NULL;
    yajl_val tree;
    char errbuf[1024];
    struct parser_context tmp_ctx = { 0 };

    if (jsondata == NULL || err == NULL)
      return NULL;

    *err = NULL;
    if (ctx == NULL)
     ctx = (const struct parser_context *)(&tmp_ctx);

    tree = yajl_tree_parse (jsondata, errbuf, sizeof (errbuf));
    if (tree == NULL)
      {
        if (asprintf (err, "cannot parse the data: %s", errbuf) < 0)
            *err = strdup ("error allocating memory");
        return NULL;
      }
    ptr = make_image_spec_schema_image_manifest_schema (tree, ctx, err);
    yajl_tree_free (tree);
    return ptr;
}
char *image_spec_schema_image_manifest_schema_generate_json(const image_spec_schema_image_manifest_schema *ptr, const struct parser_context *ctx, parser_error *err)
{
    yajl_gen g = NULL;
    struct parser_context tmp_ctx = { 0 };
    const unsigned char *gen_buf = NULL;
    char *json_buf = NULL;
    size_t gen_len = 0;

    if (ptr == NULL || err == NULL)
      return NULL;

    *err = NULL;
    if (ctx == NULL)
        ctx = (const struct parser_context *)(&tmp_ctx);

    if (!json_gen_init(&g, ctx))
      {
        *err = strdup ("Json_gen init failed");
        goto out;
      }

    if (yajl_gen_status_ok != gen_image_spec_schema_image_manifest_schema (g, ptr, ctx, err))
      {
        if (*err == NULL)
            *err = strdup ("Failed to generate json");
        goto free_out;
      }

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

    json_buf = calloc (1, gen_len + 1);
    if (json_buf == NULL)
      {
        *err = strdup ("Cannot allocate memory");
        goto free_out;
      }
    (void) 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;
}
