package handlers_test

import (
	"fmt"
	"net/http"
	"otaupdate/handlers"
	"otaupdate/services"
	"testing"

	"github.com/fiskerinc/cloud-services/pkg/common"
	orm "github.com/fiskerinc/cloud-services/pkg/db/queries"
	mo "github.com/fiskerinc/cloud-services/pkg/db/queries/mocks"
	th "github.com/fiskerinc/cloud-services/pkg/testhelper"
	"github.com/google/uuid"
)

func TestSubscriptionConfigsGetList(t *testing.T) {
	mock := mo.MockSubscriptionConfigurations{}
	services.GetDB().SetSubConfigurations(&mock)
	testFeatureID := uuid.MustParse("ecfb89e0-ca03-4aa9-a43a-a9d703256edb")
	testConfiguration := common.BinaryHex{0x46, 0x44, 0x73, 0x81}
	testDID := common.BinaryHex{0x32, 0x45}
	testPID := common.BinaryHex{0xAA, 0xAA}
	testMask := common.BinaryHex{0x00, 0x00, 0x00, 0x10}
	listData := []common.SubscriptionConfiguration{
		{
			SubscriptionFeatureID: testFeatureID,
			ECU:                   "TEST",
			SoftwareVersion:       "SoftwareVersion",
			HardwareVersion:       "HardwareVersion",
			Configuration:         &testConfiguration,
			DID:                   &testDID,
			PID:                   &testPID,
			Mask:                  &testMask,
		},
	}
	expectedResp := `{"data":[{"feature_id":"ecfb89e0-ca03-4aa9-a43a-a9d703256edb","ecu":"TEST","sw_version":"SoftwareVersion","hw_version":"HardwareVersion","configuration":"46447381","did":"3245","pid":"aaaa","mask":"00000010"}],"total":1}`
	expectedRespNoTotal := `{"data":[{"feature_id":"ecfb89e0-ca03-4aa9-a43a-a9d703256edb","ecu":"TEST","sw_version":"SoftwareVersion","hw_version":"HardwareVersion","configuration":"46447381","did":"3245","pid":"aaaa","mask":"00000010"}]}`
	defaultOrder := "created_at DESC"

	tests := []mo.DBHttpTest{
		{
			Name:             "No parameters",
			Request:          th.MakeTestRequest(http.MethodGet, "http://example.com/subscriptionconfigs", nil),
			ExpectedStatus:   http.StatusOK,
			ExpectedResponse: expectedResp,
			DBTestCase: mo.DBTestCase{
				ExpectedFilter: &common.SubscriptionConfiguration{},
				ExpectedPage: &orm.PageQueryOptions{
					Order:  defaultOrder,
					Limit:  orm.PageQueryOptionsLimitMaximum,
					Offset: 0,
				},
				MockListResponse: listData,
			},
		},
		{
			Name:             "Feature Id parameter",
			Request:          th.MakeTestRequest(http.MethodGet, "http://example.com/subscriptionconfigs?feature_id=0557bd1d-76d3-41e5-a44e-13c479e55ab0", nil),
			ExpectedStatus:   http.StatusOK,
			ExpectedResponse: expectedResp,
			DBTestCase: mo.DBTestCase{
				ExpectedFilter: &common.SubscriptionConfiguration{
					SubscriptionFeatureID: uuid.MustParse("0557bd1d-76d3-41e5-a44e-13c479e55ab0"),
				},
				ExpectedPage: &orm.PageQueryOptions{
					Order:  defaultOrder,
					Limit:  orm.PageQueryOptionsLimitMaximum,
					Offset: 0,
				},
				MockListResponse: listData,
			},
		},
		{
			Name:             "ECU parameter",
			Request:          th.MakeTestRequest(http.MethodGet, "http://example.com/subscriptionconfigs?ecu=TEST", nil),
			ExpectedStatus:   http.StatusOK,
			ExpectedResponse: expectedResp,
			DBTestCase: mo.DBTestCase{
				ExpectedFilter: &common.SubscriptionConfiguration{
					ECU: "TEST",
				},
				ExpectedPage: &orm.PageQueryOptions{
					Order:  defaultOrder,
					Limit:  orm.PageQueryOptionsLimitMaximum,
					Offset: 0,
				},
				MockListResponse: listData,
			},
		},
		{
			Name:             "Paging parameters",
			Request:          th.MakeTestRequest(http.MethodGet, "http://example.com/subscriptionconfigs?offset=10&limit=5", nil),
			ExpectedStatus:   http.StatusOK,
			ExpectedResponse: expectedRespNoTotal,
			DBTestCase: mo.DBTestCase{
				ExpectedFilter: &common.SubscriptionConfiguration{},
				ExpectedPage: &orm.PageQueryOptions{
					Order:  defaultOrder,
					Limit:  5,
					Offset: 10,
				},
				MockListResponse: listData,
			},
		},
		{
			Name:             "Error",
			Request:          th.MakeTestRequest(http.MethodGet, "http://example.com/subscriptionconfigs", nil),
			ExpectedStatus:   http.StatusServiceUnavailable,
			ExpectedResponse: `{"message":"something went wrong","error":"Service Unavailable"}`,
			DBTestCase: mo.DBTestCase{
				ExpectedFilter: &common.SubscriptionConfiguration{},
				ExpectedPage: &orm.PageQueryOptions{
					Order:  defaultOrder,
					Limit:  orm.PageQueryOptionsLimitMaximum,
					Offset: 0,
				},
				MockError: fmt.Errorf("something went wrong"),
			},
		},
		{
			Name: "Wrong limit, -100",
			Request: th.MakeTestRequest(http.MethodGet, "http://example.com/subscriptionconfigs?ecu=TEST&limit=-100", nil),
			ExpectedStatus: http.StatusBadRequest,
			ExpectedResponse: `{"message":"Limit less than 0","error":"Bad Request"}`,
		},
		{
			Name: "Wrong limit, 1000",
			Request: th.MakeTestRequest(http.MethodGet, "http://example.com/subscriptionconfigs?ecu=TEST&limit=1000", nil),
			ExpectedStatus: http.StatusBadRequest,
			ExpectedResponse: `{"message":"Limit greater than 100","error":"Bad Request"}`,
		},
	}

	mo.RunDBTests(t, tests, handlers.HandleSubscriptionConfigsGetList, &mock)
}
