#include "reading_io.h"
#include "json.h"

#include <string.h>

/* Mirrors astro.c's own k_body_slug/k_aspect_slug (its i18n lookup-key
 * tables), duplicated here rather than linking astro.c into this
 * otherwise header-only, independently testable module - same policy
 * and same reasoning as significance.c's max_orb_for_pair(). Keep in
 * sync if those slugs ever change. */
static const char *const k_body_slug[NUM_BODIES] = {
  "sun", "moon", "mercury", "venus", "mars",
  "jupiter", "saturn", "uranus", "neptune", "pluto",
};

static const char *const k_aspect_slug[5] = {
  "conjunction", "sextile", "square", "trine", "opposition",
};

static bool body_from_slug(const char *slug, Body *out) {
  for (int i = 0; i < NUM_BODIES; i++) {
    if (strcmp(slug, k_body_slug[i]) == 0) {
      *out = (Body)i;
      return true;
    }
  }
  return false;
}

static bool aspect_type_from_slug(const char *slug, AspectType *out) {
  for (int i = 0; i < 5; i++) {
    if (strcmp(slug, k_aspect_slug[i]) == 0) {
      *out = (AspectType)i;
      return true;
    }
  }
  return false;
}

bool reading_load_json(const char *text, size_t length, DailyReading *out) {
  memset(out, 0, sizeof(*out));

  JsonValue *root = json_parse(text, length);
  if (!root) return false;

  const JsonValue *transits = json_object_get(root, "transits");
  const JsonValue *aspects = transits ? json_object_get(transits, "aspects") : NULL;
  if (!aspects) {
    json_free(root);
    return false;
  }

  bool ok = true;
  int filled = 0;
  int count = json_array_count(aspects);
  for (int i = 0; i < count && filled < MAX_ASPECTS; i++) {
    const JsonValue *item = json_array_get(aspects, i);
    const char *transiting_slug = json_as_string(json_object_get(item, "transiting_planet"));
    const char *natal_slug = json_as_string(json_object_get(item, "natal_planet"));
    const char *type_slug = json_as_string(json_object_get(item, "type"));
    const JsonValue *orb_value = json_object_get(item, "orb");

    Body transiting, natal;
    AspectType type;
    if (!body_from_slug(transiting_slug, &transiting) ||
        !body_from_slug(natal_slug, &natal) ||
        !aspect_type_from_slug(type_slug, &type) ||
        !orb_value) {
      ok = false;
      break;
    }

    out->transits.aspects[filled].transiting_planet = transiting;
    out->transits.aspects[filled].natal_planet = natal;
    out->transits.aspects[filled].type = type;
    out->transits.aspects[filled].orb = json_as_number(orb_value);
    filled++;
  }
  out->transits.aspect_count = filled;

  json_free(root);
  return ok;
}
