#include <softbus_core/models/SoftbusTypes.h>

namespace softbus::core {

nlohmann::json SoftbusDataPoint::toJson() const
{
    return nlohmann::json{
        {"deviceId", deviceId},
        {"pointId", pointId},
        {"value", value},
        {"unit", unit},
        {"quality", qualityToString(quality)},
        {"sourceTimestamp", sourceTimestampNs},
        {"sequence", sequence},
        {"objectRef", objectRef}
    };
}

SoftbusDataPoint SoftbusDataPoint::fromJson(const nlohmann::json& j)
{
    SoftbusDataPoint dp;
    dp.deviceId = j.value("deviceId", "");
    dp.pointId = j.value("pointId", "");
    dp.value = j.value("value", 0.0);
    dp.unit = j.value("unit", "");
    dp.sourceTimestampNs = j.value("sourceTimestamp", static_cast<std::uint64_t>(0));
    dp.sequence = j.value("sequence", static_cast<std::uint64_t>(0));
    dp.objectRef = j.value("objectRef", "");
    const auto q = j.value("quality", "GOOD");
    if (q == "BAD") {
        dp.quality = SoftbusQuality::Bad;
    } else if (q == "OUT_OF_RANGE") {
        dp.quality = SoftbusQuality::OutOfRange;
    } else if (q == "STALE") {
        dp.quality = SoftbusQuality::Stale;
    } else if (q == "UNCERTAIN") {
        dp.quality = SoftbusQuality::Uncertain;
    }
    return dp;
}

nlohmann::json SoftbusAck::toJson() const
{
    return nlohmann::json{
        {"type", "ack"},
        {"requestId", requestId},
        {"traceId", traceId},
        {"deviceId", deviceId},
        {"pointId", pointId},
        {"success", success},
        {"error", error},
        {"executedValue", executedValue}
    };
}

SoftbusAck SoftbusAck::fromJson(const nlohmann::json& j)
{
    SoftbusAck ack;
    ack.requestId = j.value("requestId", "");
    ack.traceId = j.value("traceId", "");
    ack.deviceId = j.value("deviceId", "");
    ack.pointId = j.value("pointId", "");
    ack.success = j.value("success", false);
    ack.error = j.value("error", "");
    ack.executedValue = j.value("executedValue", 0.0);
    return ack;
}

nlohmann::json SoftbusEvent::toJson() const
{
    return nlohmann::json{
        {"deviceId", deviceId},
        {"eventType", eventType},
        {"message", message},
        {"timestamp", timestampNs}
    };
}

SoftbusEvent SoftbusEvent::fromJson(const nlohmann::json& j)
{
    SoftbusEvent ev;
    ev.deviceId = j.value("deviceId", "");
    ev.eventType = j.value("eventType", "");
    ev.message = j.value("message", "");
    ev.timestampNs = j.value("timestamp", static_cast<std::uint64_t>(0));
    return ev;
}

std::string qualityToString(SoftbusQuality q)
{
    switch (q) {
    case SoftbusQuality::Bad: return "BAD";
    case SoftbusQuality::Uncertain: return "UNCERTAIN";
    case SoftbusQuality::OutOfRange: return "OUT_OF_RANGE";
    case SoftbusQuality::Stale: return "STALE";
    default: return "GOOD";
    }
}

SignalType signalTypeFromString(const std::string& s)
{
    if (s == "AI") return SignalType::AI;
    if (s == "AO") return SignalType::AO;
    if (s == "DI") return SignalType::DI;
    if (s == "DO") return SignalType::DO;
    return SignalType::Unknown;
}

std::string signalTypeToString(SignalType t)
{
    switch (t) {
    case SignalType::AI: return "AI";
    case SignalType::AO: return "AO";
    case SignalType::DI: return "DI";
    case SignalType::DO: return "DO";
    default: return "Unknown";
    }
}

PointAccess accessFromString(const std::string& s)
{
    if (s == "read") return PointAccess::Read;
    if (s == "write") return PointAccess::Write;
    if (s == "read_write") return PointAccess::ReadWrite;
    return PointAccess::Read;
}

} // namespace softbus::core
