package handlers_test

import (
	"testing"

	"github.com/fiskerinc/cloud-services/services/attendant/handlers"
	"github.com/fiskerinc/cloud-services/services/attendant/services"

	"github.com/fiskerinc/cloud-services/pkg/testhelper"
	vconfig "github.com/fiskerinc/cloud-services/pkg/vehicleconfig"
)

func TestUpdateCarState(t *testing.T) {
	setupDBMock()
	setupRedisMock()

	mockSap := vconfig.SAPServiceMock{}
	services.SetSapService(mockSap)

	type testCase struct {
		Name        string
		VIN         string
		Payload     string
		ExpectedErr string
	}

	tests := []testCase{
		{
			Name:        "Empty ECU",
			VIN:         "JH4KA7680RC011845",
			Payload:     `{"ecus": {}}`,
			ExpectedErr: "Key: 'CarStateUpdate.ECUs' Error:Field validation for 'ECUs' failed on the 'min' tag",
		},
		{
			Name: "Bad VIN and ECU",
			VIN:  "JH4KA7680RC01",
			Payload: `{
				"ecus": {
					"ECU1": {
						"serial_number": "AAAAA",
						"hw_version": "2000",
						"boot_loader_version": "3000",
						"fingerprint": "0xffffffffffffffffff",
						"config": "0x024000941f9fffbfffe2dd9bff5860000007dfff091fff7f",
						"vendor": "A021E00029"
					}
				}
			}`,
			ExpectedErr: "Key: 'CarECU.VIN' Error:Field validation for 'VIN' failed on the 'vin' tag",
		},
		{
			Name: "Good ECUs with/without software version",
			VIN:  "JH4KA7680RC011845",
			Payload: `{
				"ecus": {
					"ECU1": {
						"sw_version": "1000",
						"serial_number": "AAAAA",
						"hw_version": "2000",
						"boot_loader_version": "3000",
						"fingerprint": "0xffffffffffffffffff",
						"config": "0x024000941f9fffbfffe2dd9bff5860000007dfff091fff7f",
						"vendor": "A021E00029"
					},
					"ECU2": {
						"serial_number": "BBBBBBB",
						"hw_version": "2001",
						"boot_loader_version": "3001",
						"fingerprint": "0xffffffffffffffffff",
						"config": "0x024000941f9fffbfffe2dd9bff5860000007dfff091fff7f",
						"vendor": "A021E00029"
					}
				}
			}`,
			ExpectedErr: "",
		},
		{
			Name: "bad ECU followed by a Good ECU",
			VIN:  "JH4KA7680RC011845",
			Payload: `{
				"ecus": {
					"ECU1": {
						"serial_number": "AAAAA",
						"hw_version": "2000",
						"boot_loader_version": "3000",
						"fingerprint": "0xffffffffffffffffff",
						"config": "0x024000941f9fffbfffe2dd9bff5860000007dfff091fff7f",
						"vendor": "A021E00029",
						"epoch_usec": "ABC"
					},
					"ECU2": {
						"serial_number": "BBBBBBB",
						"hw_version": "2001",
						"boot_loader_version": "3001",
						"fingerprint": "0xffffffffffffffffff",
						"config": "0x024000941f9fffbfffe2dd9bff5860000007dfff091fff7f",
						"vendor": "A021E00029"
					}
				}
			}`,
			ExpectedErr: "json: cannot unmarshal string into Go struct field CarECU.ecus.epoch_usec of type int64",
		},
	}

	for _, test := range tests {
		err := handlers.UpdateCarState(mockDB, test.VIN, []byte(test.Payload))
		if err != nil && test.ExpectedErr != err.Error() {
			t.Errorf(testhelper.TestErrorTemplate, test.Name, test.ExpectedErr, err.Error())
		} else if err == nil && test.ExpectedErr != "" {
			t.Errorf(testhelper.TestErrorTemplate, test.Name, test.ExpectedErr, err)
		}
	}
}
