#ifndef CCT_RUNTIME_H
#define CCT_RUNTIME_H

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdarg.h>

// Fixed-point probability type: Q16.16 (32-bit)
typedef int32_t cct_prob_t;
#define CCT_PROB_ONE (1 << 16)
#define CCT_PROB_HALF (1 << 15)
#define CCT_PROB_MAX INT32_MAX

// Convert between float and fixed-point
static inline cct_prob_t cct_float_to_prob(float f) {
    return (cct_prob_t)(f * CCT_PROB_ONE);
}
static inline float cct_prob_to_float(cct_prob_t p) {
    return (float)p / CCT_PROB_ONE;
}

// Basic arithmetic
static inline cct_prob_t cct_addp(cct_prob_t a, cct_prob_t b) {
    // convolution for probabilities (assuming independent, simple sum for small range)
    // In full CCT-Lang, addp is convolution, but here we approximate for demo.
    return a + b;
}
static inline cct_prob_t cct_multp(cct_prob_t a, cct_prob_t b) {
    return (cct_prob_t)(((int64_t)a * b) >> 16);
}
static inline cct_prob_t cct_logp(cct_prob_t p) {
    float f = cct_prob_to_float(p);
    return cct_float_to_prob(logf(f));
}
static inline cct_prob_t cct_exp(cct_prob_t x) {
    float f = cct_prob_to_float(x);
    return cct_float_to_prob(expf(f));
}
static inline float cct_log(float x) { return logf(x); }
static inline float cct_expf(float x) { return expf(x); }

// Timer functions
static inline uint32_t cct_start_timer(void) {
    return clock();
}
static inline uint32_t cct_stop_timer(uint32_t start) {
    return (clock() - start) * 1000000 / CLOCKS_PER_SEC;
}

// Print with format (simplified)
void cct_print(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    vprintf(fmt, args);
    va_end(args);
}

#endif