// Copyright 2011-2022 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC

#include "world.h"

#include "log.h"
#include "node.h"

#include "serd/node.h"
#include "serd/status.h"
#include "serd/string_view.h"
#include "serd/world.h"

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

SerdWorld*
serd_world_new(void)
{
  SerdWorld* world      = (SerdWorld*)calloc(1, sizeof(SerdWorld));
  SerdNode*  blank_node = serd_new_blank(serd_string("b00000000000"));

  if (!world || !blank_node) {
    serd_node_free(blank_node);
    free(world);
    return NULL;
  }

  world->limits.reader_stack_size = 1048576U;
  world->limits.writer_max_depth  = 128U;
  world->blank_node               = blank_node;

  serd_log_init(&world->log);

  return world;
}

void
serd_world_free(SerdWorld* const world)
{
  if (world) {
    serd_node_free(world->blank_node);
    free(world);
  }
}

SerdLimits
serd_world_limits(const SerdWorld* const world)
{
  assert(world);
  return world->limits;
}

SerdStatus
serd_world_set_limits(SerdWorld* const world, const SerdLimits limits)
{
  assert(world);
  world->limits = limits;
  return SERD_SUCCESS;
}

const SerdNode*
serd_world_get_blank(SerdWorld* const world)
{
#define BLANK_CHARS 12

  assert(world);

  char* buf = serd_node_buffer(world->blank_node);
  memset(buf, 0, BLANK_CHARS + 1);

  world->blank_node->length =
    (size_t)snprintf(buf, BLANK_CHARS + 1, "b%u", ++world->next_blank_id);

  return world->blank_node;

#undef BLANK_CHARS
}