namespace ConeCalorimeter.Services;

public enum ModbusFloatByteOrder
{
    Abcd,
    Cdab,
    Badc,
    Dcba
}

public readonly record struct ModbusFloatReadResult(byte A, byte B, byte C, byte D)
{
    public string RawHex => $"{A:X2} {B:X2} {C:X2} {D:X2}";

    public double Abcd => Decode(A, B, C, D);

    public double Cdab => Decode(C, D, A, B);

    public double Badc => Decode(B, A, D, C);

    public double Dcba => Decode(D, C, B, A);

    public double GetValue(ModbusFloatByteOrder byteOrder)
    {
        return byteOrder switch
        {
            ModbusFloatByteOrder.Abcd => Abcd,
            ModbusFloatByteOrder.Cdab => Cdab,
            ModbusFloatByteOrder.Badc => Badc,
            ModbusFloatByteOrder.Dcba => Dcba,
            _ => double.NaN
        };
    }

    private static double Decode(byte b0, byte b1, byte b2, byte b3)
    {
        var rawValue = unchecked((int)(
            ((uint)b0 << 24)
            | ((uint)b1 << 16)
            | ((uint)b2 << 8)
            | b3));

        return BitConverter.Int32BitsToSingle(rawValue);
    }
}
