#include "value.h"

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

// Un decimal con más caracteres queda como cadena: así, siempre cabe en un double.
#define DECIMAL_MAX_LENGTH 64

// --- Hecho: lean estas funciones, no hace falta cambiarlas. ---

Value value_none(void) {
    Value v;
    v.kind = VALUE_NONE;
    return v;
}

Value value_int(int n) {
    Value v;
    v.kind = VALUE_INT;
    v.as.integer = n;
    return v;
}

// Avanza por los dígitos desde text[i], y devuelve dónde se detuvo.
static int skip_digits(const char *text, int i) {
    while (text[i] >= '0' && text[i] <= '9') {
        i++;
    }
    return i;
}

// Convierte solo dígitos. Revisa ANTES de multiplicar: después ya sería overflow.
static int digits_to_int(const char *digits, int *result) {
    int value = 0;
    for (int i = 0; digits[i] != '\0'; i++) {
        int digit = digits[i] - '0';
        if (value > (INT_MAX - digit) / 10) {
            return 0;
        }
        value = value * 10 + digit;
    }
    *result = value;
    return 1;
}

Value value_parse(const char *field) {
    if (field[0] == '\0') {
        return value_none();
    }

    int start = field[0] == '-' ? 1 : 0;
    int end = skip_digits(field, start);

    if (end > start && field[end] == '\0') {
        int n;
        if (digits_to_int(field + start, &n)) {
            return value_int(start == 1 ? -n : n);
        }
        return value_string(field);
    }

    if (end > start && field[end] == '.') {
        int after = end + 1;
        int last = skip_digits(field, after);
        double x;
        if (last > after && field[last] == '\0' && last <= DECIMAL_MAX_LENGTH &&
            sscanf(field, "%lf", &x) == 1) {
            return value_double(x);
        }
    }
    return value_string(field);
}

// --- Por escribir. Lo que debe hacer cada una está en value.h. ---

Value value_double(double x) {
    (void) x;
    return value_none();
}

Value value_string(const char *s) {
    (void) s;
    return value_none();
}

void value_print(const Value *v) {
    (void) v;
}

int value_equal(const Value *a, const Value *b) {
    (void) a;
    (void) b;
    return 0;
}

void value_free(Value *v) {
    (void) v;
}
