package handlers_test

import (
	"net/http"
	"testing"

	"github.com/fiskerinc/cloud-services/pkg/common"
	"github.com/fiskerinc/cloud-services/pkg/httpclient/tester"
	km "github.com/fiskerinc/cloud-services/pkg/kafka/mock"
	th "github.com/fiskerinc/cloud-services/pkg/testhelper"
	"github.com/fiskerinc/cloud-services/pkg/testrunner"

	"otaupdate/handlers"
	"otaupdate/services"
)

func TestVehicleCommand(t *testing.T) {
	vin := "1G1FP87S3GN100062"
	mockKafka := km.KafkaMock{}
	services.SetKafkaProducer(&mockKafka)

	tests := []testrunner.TestCase{
		{
			Name: "Unlock command",
			HttpTestCase: &tester.HttpTestCase{
				Request: th.MakeTestRequest(http.MethodPost, "http://example.com/vehiclecommand", common.BulkCarCommands{
					VINs: []string{vin},
					RemoteCommandSource: common.RemoteCommandSource{
						Command: "doors_unlock",
					},
				}),
				ExpectedStatus:   http.StatusOK,
				ExpectedResponse: `{"message":"remote command sent to 1 vehicles"}`,
			},
		},
		{
			Name: "No data",
			HttpTestCase: &tester.HttpTestCase{
				Request:          th.MakeTestRequest(http.MethodPost, "http://example.com/vehiclecommand", nil),
				ExpectedStatus:   http.StatusBadRequest,
				ExpectedResponse: `{"message":"VINs required. Command required","error":"Bad Request"}`,
			},
		},
		{
			Name: "Bad VIN data",
			HttpTestCase: &tester.HttpTestCase{
				Request: th.MakeTestRequest(http.MethodPost, "http://example.com/vehiclecommand", common.BulkCarCommands{
					VINs: []string{vin, "XXXXX"},
					RemoteCommandSource: common.RemoteCommandSource{
						Command: "TEST",
						Data:    stringPointer("TEST_PARAMETERS"),
					},
				}),
				ExpectedStatus:   http.StatusBadRequest,
				ExpectedResponse: `{"message":"VINs[1] 'XXXXX' invalid","error":"Bad Request"}`,
			},
		},
		{
			Name: "Bad command",
			HttpTestCase: &tester.HttpTestCase{
				Request: th.MakeTestRequest(http.MethodPost, "http://example.com/vehiclecommand", common.BulkCarCommands{
					VINs: []string{vin},
					RemoteCommandSource: common.RemoteCommandSource{
						Command: "TEST",
						Data:    stringPointer("TEST_PARAMETERS"),
					},
				}),
				ExpectedStatus:   http.StatusBadRequest,
				ExpectedResponse: `{"message":"unknown command","error":"Bad Request"}`,
			},
		},
		{
			Name: "Lock command",
			HttpTestCase: &tester.HttpTestCase{
				Request: th.MakeTestRequest(http.MethodPost, "http://example.com/vehiclecommand", common.BulkCarCommands{
					VINs: []string{vin},
					RemoteCommandSource: common.RemoteCommandSource{
						Command: "doors_lock",
					},
				}),
				ExpectedStatus:   http.StatusOK,
				ExpectedResponse: `{"message":"remote command sent to 1 vehicles"}`,
			},
		},
		{
			Name: "Vent windows",
			HttpTestCase: &tester.HttpTestCase{
				Request: th.MakeTestRequest(http.MethodPost, "http://example.com/vehiclecommand", common.BulkCarCommands{
					VINs: []string{"1G1FP87S3GN100062"},
					RemoteCommandSource: common.RemoteCommandSource{
						Command: "vent_windows",
					},
				}),
				ExpectedStatus:   http.StatusOK,
				ExpectedResponse: `{"message":"remote command sent to 1 vehicles"}`,
			},
		},
		{
			Name: "Close window",
			HttpTestCase: &tester.HttpTestCase{
				Request: th.MakeTestRequest(http.MethodPost, "http://example.com/vehiclecommand", common.BulkCarCommands{
					VINs: []string{"1G1FP87S3GN100062"},
					RemoteCommandSource: common.RemoteCommandSource{
						Command: "close_windows",
					},
				}),
				ExpectedStatus:   http.StatusOK,
				ExpectedResponse: `{"message":"remote command sent to 1 vehicles"}`,
			},
		},
	}

	for _, test := range tests {
		w := test.HttpTestCase.Test(handlers.HandleVehicleCommand)
		test.HttpTestCase.ValidateHttp(t, test.Name, w)
	}
}

func stringPointer(s string) *string {
	return &s
}
