package validator_test

import (
	"testing"

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

type TestCar struct {
	VIN      string `validate:"vin,len=17"`
	Expected string
}

var vinValidatorValidTests = []TestCar{
	{
		VIN: "1G1FP87S3GN100062",
	},
	{
		VIN: "1HTSDN2NXPH482591",
	},
	{
		VIN: "2C4RDGCG0DR641898",
	},
	{
		VIN: "2FMZA5149YBC02439",
	},
	{
		VIN: "2G1FA1E38E9309317",
	},
	{
		VIN: "2HNYD18245H511789",
	},
	{
		VIN: "3C4PDCBG0ET127145",
	},
	{
		VIN: "4JGBB86E46A022490",
	},
	{
		VIN: "5UXCY6C01M9E72005",
	},
	{
		VIN: "JTDKN3DU7A0198862",
	},
	{
		VIN: "KL1TD56647B195973",
	},
	{
		VIN: "WBABS53402JU44262",
	},
	{
		VIN: "YV1CZ852251176667",
	},
}

func TestValidateVIN(t *testing.T) {
	var tests = []TestCar{
		{
			VIN:      "XXXXXXXXXXXX",
			Expected: "Key: 'TestCar.VIN' Error:Field validation for 'VIN' failed on the 'vin' tag",
		},
		{
			VIN:      "XXXXXXXXXXXXXXXXXXXXXX",
			Expected: "Key: 'TestCar.VIN' Error:Field validation for 'VIN' failed on the 'vin' tag",
		},
	}

	tests = append(tests, vinValidatorValidTests...)

	for _, test := range tests {
		err := validator.ValidateStruct(test)
		if err == nil && test.Expected != "" {
			t.Errorf(testhelper.TestErrorTemplate, test.VIN, test.Expected, err)
		} else if err != nil && err.Error() != test.Expected {
			t.Errorf(testhelper.TestErrorTemplate, test.VIN, test.Expected, err.Error())
		}
	}
}

func TestValidateVINs(t *testing.T) {
	tests := []struct {
		VINs     string
		Expected string
	}{
		{
			VINs: "1G1FP87S3GN100062,1HTSDN2NXPH482591,2C4RDGCG0DR641898,2FMZA5149YBC02439",
		},
		{
			VINs:     "1G1FP87S3GN100062,1HTSDN2NXPH482591,2C4RDGCG0DR641898,2FMZA5149YBC02439,XXXXXXXXXXXX",
			Expected: "Key: '' Error:Field validation for '' failed on the 'vins' tag",
		},
		{
			VINs:     "XXXXXXXXXXXX,YYYYYYYYYYYY,ZZZZZZZZZZZZ",
			Expected: "Key: '' Error:Field validation for '' failed on the 'vins' tag",
		},
	}

	for _, test := range tests {
		err := validator.GetValidator().Var(test.VINs, "vins")
		if err == nil && test.Expected != "" {
			t.Errorf(testhelper.TestErrorTemplate, test.VINs, test.Expected, err)
		} else if err != nil && err.Error() != test.Expected {
			t.Errorf(testhelper.TestErrorTemplate, test.VINs, test.Expected, err.Error())
		}
	}
}

func TestValidateVINSuffix(t *testing.T) {
	tests := []struct {
		vin    string
		expErr string
	}{
		{vin: "N100062"},
		{vin: "H482591"},
		{vin: "R641898"},
		{vin: "BC02439"},
		{vin: "9309317"},
		{vin: "H511789"},
		{vin: "T127145"},
		{vin: "A022490"},
		{vin: "9E72005"},
		{vin: "0198862"},
		{vin: "B195973"},
		{vin: "JU44262"},
		{vin: "1176667"},
		{vin: "XXXXXX", expErr: "Key: '' Error:Field validation for '' failed on the 'vinsuffix' tag"},
		{vin: "XXXXXXXX", expErr: "Key: '' Error:Field validation for '' failed on the 'vinsuffix' tag"},
		{vin: "XXXXXXO", expErr: "Key: '' Error:Field validation for '' failed on the 'vinsuffix' tag"},
	}

	for _, test := range tests {
		err := validator.GetValidator().Var(test.vin, "vinsuffix")
		if err == nil && test.expErr != "" {
			t.Errorf(testhelper.TestErrorTemplate, test.vin, test.expErr, err)
		} else if err != nil && err.Error() != test.expErr {
			t.Errorf(testhelper.TestErrorTemplate, test.vin, test.expErr, err.Error())
		}
	}
}

func TestValidateICCIDSimple(t *testing.T) {
	tests := []struct {
		iccid  string
		match  bool
		expErr string
	}{
		{iccid: "8901882000784174124F", match: true},
		{iccid: "8901882000784174124", match: true},
		{iccid: "8901882000784174124FF"},
		{iccid: "SSSSSSSSS"},
	}

	for _, test := range tests {
		matched, err := validator.ValidateICCIDSimple(test.iccid)
		if matched != test.match {
			t.Errorf(testhelper.TestErrorTemplate, test.iccid, test.match, matched)
		}
		if err == nil && test.expErr != "" {
			t.Errorf(testhelper.TestErrorTemplate, test.iccid, test.expErr, err)
		} else if err != nil && err.Error() != test.expErr {
			t.Errorf(testhelper.TestErrorTemplate, test.iccid, test.expErr, err.Error())
		}
	}

}
