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"
	"github.com/fiskerinc/cloud-services/pkg/httpclient/tester"
	th "github.com/fiskerinc/cloud-services/pkg/testhelper"
	"github.com/fiskerinc/cloud-services/pkg/testrunner"
)

func TestHandleSuppliersGetList(t *testing.T) {
	supplier := common.SupplierAccount{
		SupplierOrganizationID: 14,
		Email:                  "test@supplier.com",
		Company:                "TEST",
		Address:                "100 Main",
		Contact:                "John Doe",
		Telephone:              "+1-555-555-5555",
		Program:                "Ocean",
		ECUs:                   []string{"ADAS"},
	}
	mock := mo.MockSupplierAccounts{}
	services.GetDB().SetSupplierAccount(&mock)
	expectedSupplier := `{"supplier_organization_id":"14","email":"test@supplier.com","company":"TEST","address":"100 Main","contact":"John Doe","telephone":"+1-555-555-5555","program":"Ocean","ecus":["ADAS"]}`
	expectedResp := fmt.Sprintf(`{"data":[%s],"total":1}`, expectedSupplier)
	expectedRespNoTotal := fmt.Sprintf(`{"data":[%s]}`, expectedSupplier)
	defaultOrder := "created_at DESC"
	listData := []common.SupplierAccount{supplier}

	tests := []testrunner.TestCase{
		{
			Name: "Error",
			HttpTestCase: &tester.HttpTestCase{
				Request:          th.MakeTestRequest(http.MethodGet, "http://example.com/suppliers", nil),
				ExpectedStatus:   http.StatusServiceUnavailable,
				ExpectedResponse: `{"message":"something went wrong","error":"Service Unavailable"}`,
			},
			DBTestCase: &mo.DBTestCase{
				ExpectedFilter: &common.SupplierAccount{},
				ExpectedPage: &orm.PageQueryOptions{
					Order:  defaultOrder,
					Limit:  orm.PageQueryOptionsLimitMaximum,
					Offset: 0,
				},
				MockError: fmt.Errorf("something went wrong"),
			},
		},
		{
			Name: "No parameters",
			HttpTestCase: &tester.HttpTestCase{
				Request:          th.MakeTestRequest(http.MethodGet, "http://example.com/suppliers", nil),
				ExpectedStatus:   http.StatusOK,
				ExpectedResponse: expectedResp,
			},
			DBTestCase: &mo.DBTestCase{
				ExpectedFilter: &common.SupplierAccount{},
				ExpectedPage: &orm.PageQueryOptions{
					Order:  defaultOrder,
					Limit:  orm.PageQueryOptionsLimitMaximum,
					Offset: 0,
				},
				MockListResponse: listData,
			},
		},
		{
			Name: "Email parameter",
			HttpTestCase: &tester.HttpTestCase{
				Request:          th.MakeTestRequest(http.MethodGet, "http://example.com/suppliers?email=test@supplier.com", nil),
				ExpectedStatus:   http.StatusOK,
				ExpectedResponse: expectedRespNoTotal,
			},
			DBTestCase: &mo.DBTestCase{
				ExpectedFilter: &common.SupplierAccount{
					Email: "test@supplier.com",
				},
				ExpectedPage: &orm.PageQueryOptions{
					Order:  defaultOrder,
					Limit:  orm.PageQueryOptionsLimitMaximum,
					Offset: 0,
				},
				MockListResponse: listData,
			},
		},
		{
			Name: "Paging parameters",
			HttpTestCase: &tester.HttpTestCase{
				Request:          th.MakeTestRequest(http.MethodGet, "http://example.com/suppliers?offset=10&limit=5", nil),
				ExpectedStatus:   http.StatusOK,
				ExpectedResponse: expectedRespNoTotal,
			},
			DBTestCase: &mo.DBTestCase{
				ExpectedFilter: &common.SupplierAccount{},
				ExpectedPage: &orm.PageQueryOptions{
					Order:  defaultOrder,
					Limit:  5,
					Offset: 10,
				},
				MockListResponse: listData,
			},
		},
		{
			Name: "Wrong limit, -100",
			HttpTestCase: &tester.HttpTestCase{
				Request:          th.MakeTestRequest(http.MethodGet, "http://example.com/suppliers?email=test@supplier.com&limit=-100", nil),
				ExpectedStatus:   http.StatusBadRequest,
				ExpectedResponse: `{"message":"Limit less than 0","error":"Bad Request"}`,
			},
		},
		{
			Name: "Wrong limit, 1000",
			HttpTestCase: &tester.HttpTestCase{
				Request:          th.MakeTestRequest(http.MethodGet, "http://example.com/suppliers?email=test@supplier.com&limit=1000", nil),
				ExpectedStatus:   http.StatusBadRequest,
				ExpectedResponse: `{"message":"Limit greater than 100","error":"Bad Request"}`,
			},
		},
	}

	for _, test := range tests {
		if test.DBTestCase != nil {
			test.DBTestCase.SetupDB(&mock)
		}

		w := test.HttpTestCase.Test(handlers.HandleSuppliersGetList)

		test.HttpTestCase.ValidateHttp(t, test.Name, w)
	}
}
