package com.lingniu.ingest.api.event;

/**
 * One normalized telemetry field value.
 *
 * <p>Protocol mappers use stable internal field keys so Kafka, TDengine, Redis,
 * and statistics do not depend on protocol-specific names.
 *
 * <p>{@code value} 统一用字符串承载，真实类型由 {@code valueType} 表达。这样 Kafka
 * protobuf、CSV 导出、JSON 字段和前端展示可以共用同一份字段结构；数值精度/格式化
 * 由查询层或前端按 {@code valueType + unit} 决定。
 */
public record TelemetryFieldValue(
        String key,
        ValueType valueType,
        String value,
        String unit,
        Quality quality,
        String sourcePath
) {

    public TelemetryFieldValue {
        if (key == null || key.isBlank()) {
            throw new IllegalArgumentException("key must not be blank");
        }
        if (valueType == null) {
            throw new IllegalArgumentException("valueType must not be null");
        }
        value = value == null ? "" : value;
        unit = unit == null ? "" : unit;
        // 默认 GOOD，只有解析器明确知道异常/无效/缺失时才降级，避免调用方到处补质量字段。
        quality = quality == null ? Quality.GOOD : quality;
        sourcePath = sourcePath == null ? "" : sourcePath;
    }

    public static TelemetryFieldValue stringValue(String key, String value, String unit, String sourcePath) {
        return new TelemetryFieldValue(key, ValueType.STRING, value, unit, Quality.GOOD, sourcePath);
    }

    public static TelemetryFieldValue doubleValue(String key, double value, String unit, String sourcePath) {
        return new TelemetryFieldValue(key, ValueType.DOUBLE, Double.toString(value), unit, Quality.GOOD, sourcePath);
    }

    public static TelemetryFieldValue longValue(String key, long value, String unit, String sourcePath) {
        return new TelemetryFieldValue(key, ValueType.LONG, Long.toString(value), unit, Quality.GOOD, sourcePath);
    }

    public static TelemetryFieldValue booleanValue(String key, boolean value, String unit, String sourcePath) {
        return new TelemetryFieldValue(key, ValueType.BOOLEAN, Boolean.toString(value), unit, Quality.GOOD, sourcePath);
    }

    public static TelemetryFieldValue instantValue(String key, String value, String unit, String sourcePath) {
        return new TelemetryFieldValue(key, ValueType.INSTANT, value, unit, Quality.GOOD, sourcePath);
    }

    public static TelemetryFieldValue jsonValue(String key, String value, String unit, String sourcePath) {
        return new TelemetryFieldValue(key, ValueType.JSON, value, unit, Quality.GOOD, sourcePath);
    }

    public static TelemetryFieldValue missing(String key, String unit, String sourcePath) {
        return new TelemetryFieldValue(key, ValueType.STRING, "", unit, Quality.MISSING, sourcePath);
    }

    public enum ValueType {
        STRING,
        DOUBLE,
        LONG,
        BOOLEAN,
        INSTANT,
        JSON
    }

    public enum Quality {
        GOOD,
        ESTIMATED,
        INVALID,
        MISSING
    }
}
