/* A fictional parcel shop's tariff, shared by native and Wasm hosts. */
#include "detlef_sdk.h"

static DetlefSdkStatus quote(DetlefSdkCall *call, DetlefSdkValue *result) {
    DetlefSdkValue weight_argument = 0, express_argument = 0;
    int64_t weight_grams = 0;
    DetlefSdkBool express = DETLEF_SDK_FALSE;
    DETLEF_SDK_TRY(detlef_sdk_argument(call, 0, &weight_argument));
    DETLEF_SDK_TRY(detlef_sdk_argument(call, 1, &express_argument));
    DETLEF_SDK_TRY(detlef_sdk_get_integer(call, weight_argument, &weight_grams));
    DETLEF_SDK_TRY(detlef_sdk_get_boolean(call, express_argument, &express));

    if (weight_grams < 1 || weight_grams > 20000)
        return detlef_sdk_error(
            call, "parcel weight must be between 1 and 20000 grams");

    /* 350 cents plus 75 per started 500 g; express adds 500 cents. */
    int64_t bands = (weight_grams + 499) / 500;
    int64_t price_cents = 350 + bands * 75 + (express ? 500 : 0);
    DetlefSdkValue fields[3] = {0, 0, 0};
    DETLEF_SDK_TRY(detlef_sdk_integer(call, price_cents, &fields[0]));
    DETLEF_SDK_TRY(detlef_sdk_integer(call, express ? 1 : 3, &fields[1]));
    if (express)
        DETLEF_SDK_TRY(detlef_sdk_string(
            call, "express", sizeof("express") - 1, &fields[2]));
    else
        DETLEF_SDK_TRY(detlef_sdk_string(
            call, "standard", sizeof("standard") - 1, &fields[2]));

    /* Field handles are callback-local and are cleaned up automatically. */
    return detlef_sdk_record(
        call, "CourierQuote", fields, DETLEF_SDK_COUNT(fields), result);
}

static const DetlefSdkType integer_type = DETLEF_SDK_TYPE("integer");
static const DetlefSdkType boolean_type = DETLEF_SDK_TYPE("boolean");
static const DetlefSdkType string_type = DETLEF_SDK_TYPE("string");

static const DetlefSdkField parameters[] = {
    {"weight_grams", &integer_type},
    {"express", &boolean_type},
};

static const DetlefSdkField quote_fields[] = {
    {"price_cents", &integer_type},
    {"delivery_days", &integer_type},
    {"service", &string_type},
};

static const DetlefSdkRecord records[] = {
    {"CourierQuote", quote_fields, DETLEF_SDK_COUNT(quote_fields)},
};

static const DetlefSdkCallable callables[] = {
    {"courier_quote", DETLEF_SDK_FUNCTION, quote, parameters,
     DETLEF_SDK_COUNT(parameters), NULL, NULL},
};

static const DetlefSdkPackage package = {
    callables,
    DETLEF_SDK_COUNT(callables),
    records,
    DETLEF_SDK_COUNT(records),
};

DETLEF_SDK_PACKAGE(package)
