package handlers_test

import (
	"fmt"
	"net/http"
	"testing"

	"otaupdate/handlers"
	"otaupdate/services"

	"github.com/fiskerinc/cloud-services/pkg/common"
	"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"
)

const err404NotFound = "404 page not found\n"

func TestHandleSupplierUpdate(t *testing.T) {
	route := "/supplier/:email"
	mock := mocks.MockSupplierAccounts{}
	reqGoodData := common.SupplierAccount{
		SupplierOrganizationID: 14,
		Company:                "TEST",
		Address:                "100 Main",
		Contact:                "John Doe",
		Telephone:              "+1-555-555-5555",
		Program:                "Ocean",
		ECUs:                   []string{"ADAS"},
	}

	tests := []testrunner.TestCase{
		{
			Name: "No data",
			HttpTestCase: &tester.HttpTestCase{
				Request:          th.MakeTestRequest(http.MethodPut, "http://example.com/supplier", nil),
				ExpectedStatus:   http.StatusNotFound,
				ExpectedResponse: err404NotFound,
			},
		},
		{
			Name: "Bad Data",
			HttpTestCase: &tester.HttpTestCase{
				Request: th.MakeTestRequest(http.MethodPut, "http://example.com/supplier/test", common.SupplierAccount{
					Company:   "TEST",
					Address:   "100 Main",
					Contact:   "John Doe",
					Telephone: "+1-555-555-5555",
					Program:   "Ocean",
					ECUs:      []string{},
				}),
				ExpectedStatus:   http.StatusBadRequest,
				ExpectedResponse: `{"message":"primary key required","error":"Bad Request"}`,
			},
		},
		{
			Name: "Good data",
			HttpTestCase: &tester.HttpTestCase{
				Request:          th.MakeTestRequest(http.MethodPut, "http://example.com/supplier/test@supplier.com", reqGoodData),
				ExpectedStatus:   http.StatusOK,
				ExpectedResponse: `{"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"]}`,
			},
		},
		{
			Name: "Error unregistered email",
			HttpTestCase: &tester.HttpTestCase{
				Request:          th.MakeTestRequest(http.MethodPut, "http://example.com/supplier/test@supplier.com", reqGoodData),
				ExpectedStatus:   http.StatusServiceUnavailable,
				ExpectedResponse: `{"message":"account does not exist","error":"Service Unavailable"}`,
				Setup: func() {
					mock.ORMResponse = &mocks.MockORMResults{AffectedRows: 0}
					services.GetDB().SetSupplierAccount(&mock)
				},
			},
		},
		{
			Name: "Error",
			HttpTestCase: &tester.HttpTestCase{Request: th.MakeTestRequest(http.MethodPut, "http://example.com/supplier/test@supplier.com", reqGoodData),
				ExpectedStatus:   http.StatusServiceUnavailable,
				ExpectedResponse: `{"message":"something went wrong","error":"Service Unavailable"}`,
			},
			DBTestCase: &mocks.DBTestCase{
				MockError: fmt.Errorf("something went wrong"),
			},
		},
	}

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

		mock.ORMResponse = &mocks.MockORMResults{AffectedRows: 1}
		services.GetDB().SetSupplierAccount(&mock)

		if test.HttpTestCase != nil && test.HttpTestCase.Setup != nil {
			test.HttpTestCase.Setup()
		}

		w := test.HttpTestCase.TestWithParamPath(handlers.HandleSupplierUpdate, route)

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