package m9z

import (
	"math"
	"testing"
)

func TestBuildLoopFaults(t *testing.T) {
	tests := []struct {
		name        string
		loopIdx     uint
		alarmStatus uint16
		alarmCode   string
		want        []LoopFault
	}{
		{
			name:        "short circuit",
			loopIdx:     1,
			alarmStatus: 0x01,
			alarmCode:   "01 00",
			want: []LoopFault{{
				LoopIdx: 1,
				Type:    "short_circuit",
				Message: "回路1短路故障",
				Code:    "01",
			}},
		},
		{
			name:        "open circuit",
			loopIdx:     2,
			alarmStatus: 0x02,
			alarmCode:   "02 00",
			want: []LoopFault{{
				LoopIdx: 2,
				Type:    "open_circuit",
				Message: "回路2开路故障",
				Code:    "02",
			}},
		},
		{
			name:        "power mask",
			loopIdx:     3,
			alarmStatus: 0x04,
			alarmCode:   "04 03",
			want: []LoopFault{{
				LoopIdx: 3,
				Type:    "power",
				Message: "回路3设备1/2电源故障",
				Code:    "04 03",
			}},
		},
		{
			name:        "combined faults",
			loopIdx:     4,
			alarmStatus: 0x05,
			alarmCode:   "04 02",
			want: []LoopFault{
				{
					LoopIdx: 4,
					Type:    "short_circuit",
					Message: "回路4短路故障",
					Code:    "01",
				},
				{
					LoopIdx: 4,
					Type:    "power",
					Message: "回路4设备2电源故障",
					Code:    "04 02",
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := BuildLoopFaults(tt.loopIdx, tt.alarmStatus, tt.alarmCode)
			if len(got) != len(tt.want) {
				t.Fatalf("len(got) = %d, want %d; got=%+v", len(got), len(tt.want), got)
			}
			for i := range got {
				if got[i] != tt.want[i] {
					t.Fatalf("got[%d] = %+v, want %+v", i, got[i], tt.want[i])
				}
			}
		})
	}
}

func TestParseLoopFullParametersDCCurrentScale(t *testing.T) {
	data := make([]byte, 238)
	data[2] = 0xBF
	data[3] = 0x01
	data[10] = 0x01

	params, err := ParseLoopFullParameters(data)
	if err != nil {
		t.Fatal(err)
	}
	if params == nil {
		t.Fatal("expected params, got nil")
	}
	if math.Abs(float64(params.DCCurrent-0.447)) > 0.0001 {
		t.Fatalf("DCCurrent = %v, want 0.447", params.DCCurrent)
	}
}
