package kobject_test

import (
	"reflect"
	"strconv"
	"testing"

	"hakurei.app/internal/kobject"
	"hakurei.app/internal/uevent"
)

func TestEvent(t *testing.T) {
	t.Parallel()

	testCases := []struct {
		name string
		msg  uevent.Message
		want kobject.Event
		errs []error
	}{
		{"sample coldboot qemu", uevent.Message{
			Action:  uevent.KOBJ_ADD,
			DevPath: "/devices/LNXSYSTM:00/LNXPWRBN:00",
			Env: []string{
				"ACTION=add",
				"DEVPATH=/devices/LNXSYSTM:00/LNXPWRBN:00",
				"SUBSYSTEM=acpi",
				"SYNTH_UUID=fe4d7c9d-b8c6-4a70-9ef1-3d8a58d18eed",
				"MODALIAS=acpi:LNXPWRBN:",
				"SEQNUM=777",
			}}, kobject.Event{
			Action:  uevent.KOBJ_ADD,
			DevPath: "/devices/LNXSYSTM:00/LNXPWRBN:00",
			Env: map[string]string{
				"MODALIAS": "acpi:LNXPWRBN:",
			},
			Sequence: 777,
			Synth: &uevent.UUID{
				0xfe, 0x4d, 0x7c, 0x9d,
				0xb8, 0xc6,
				0x4a, 0x70,
				0x9e, 0xf1,
				0x3d, 0x8a, 0x58, 0xd1, 0x8e, 0xed,
			},
			Subsystem: "acpi",
		}, []error{}},

		{"nil reportErr", uevent.Message{Env: []string{
			"SEQNUM=\x00",
		}}, kobject.Event{Env: map[string]string{
			"SEQNUM": "\x00",
		}}, nil},

		{"bad SEQNUM SYNTH_UUID", uevent.Message{Env: []string{
			"SEQNUM=\x00",
			"SYNTH_UUID=\x00",
			"SUBSYSTEM=\x00",
		}}, kobject.Event{Subsystem: "\x00", Env: map[string]string{
			"SEQNUM":     "\x00",
			"SYNTH_UUID": "\x00",
		}}, []error{strconv.ErrSyntax, uevent.UUIDSizeError(1)}},

		{"bad sep", uevent.Message{Env: []string{
			"SYNTH_UUID",
		}}, kobject.Event{Env: map[string]string{
			"SYNTH_UUID": "\x00",
		}}, []error{}},
	}
	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()

			var f func(error)
			gotErrs := make([]error, 0)
			if tc.errs != nil {
				f = func(err error) {
					gotErrs = append(gotErrs, err)
				}
			}

			var got kobject.Event
			got.Populate(f, &tc.msg)

			if !reflect.DeepEqual(&got, &tc.want) {
				t.Errorf("Populate: %#v, want %#v", got, tc.want)
			}
			if tc.errs != nil && !reflect.DeepEqual(gotErrs, tc.errs) {
				t.Errorf("Populate: errs = %v, want %v", gotErrs, tc.errs)
			}
		})
	}
}
