package handlers_test

import (
	"context"
	"net/http"
	"net/http/httptest"
	"otaupdate/handlers"
	"otaupdate/services"
	"testing"
	"time"

	"github.com/fiskerinc/cloud-services/pkg/common"
	"github.com/fiskerinc/cloud-services/pkg/db/queries"
	"github.com/fiskerinc/cloud-services/pkg/db/queries/mocks"
	th "github.com/fiskerinc/cloud-services/pkg/testhelper"
	"github.com/julienschmidt/httprouter"
	"github.com/stretchr/testify/assert"
)

func TestHandleVersionLogsGet(t *testing.T) {
	createdAt := time.Date(2023, 1, 13, 11, 51, 12, 0, time.UTC)
	correctVIN := "00000000000000000"
	dbMock := services.GetDB()
	dbMock.SetCars(&mocks.MockCars{})
	tests := map[string]struct {
		vin           string
		query         string
		carVersionsDB queries.CarVersionsLogInterface
		expStatus     int
		expBody       string
	}{
		"correct": {
			vin: correctVIN,
			carVersionsDB: mocks.MockCarVersionsLog{
				MockSelectByVIN: func(vin string, options *queries.PageQueryOptions) ([]common.CarVersionLogs, int, error) {
					return []common.CarVersionLogs{
						{
							ID:            1,
							VIN:           correctVIN,
							VersionSource: common.TREXVersionSource,
							Version:       "2.3.2",
							CreatedAt:     &createdAt,
						},
						{
							ID:            2,
							VIN:           correctVIN,
							VersionSource: common.DBCVersionSource,
							Version:       "hash",
							CreatedAt:     &createdAt,
						},
					}, 2, nil
				},
			},
			expStatus: http.StatusOK,
			expBody:   `{"data":[{"id":1,"vin":"00000000000000000","version_source":"TREX","version":"2.3.2","created_at":"2023-01-13T11:51:12Z"},{"id":2,"vin":"00000000000000000","version_source":"DBC","version":"hash","created_at":"2023-01-13T11:51:12Z"}],"total":2}`,
		},
		"wrong_options": {
			query:     "limit=-1",
			expStatus: http.StatusBadRequest,
			expBody:   `{"message":"Limit less than 0","error":"Bad Request"}`,
		},
		"wrong_vin": {
			expStatus: http.StatusBadRequest,
			expBody:   `{"message":"vin '' invalid","error":"Bad Request"}`,
		},
		"wrong_db": {
			vin: correctVIN,
			carVersionsDB: mocks.MockCarVersionsLog{
				MockSelectByVIN: func(vin string, options *queries.PageQueryOptions) ([]common.CarVersionLogs, int, error) {
					return nil, 0, someErr
				},
			},
			expStatus: http.StatusServiceUnavailable,
			expBody:   `{"message":"some err","error":"Service Unavailable"}`,
		},
	}
	for name, tt := range tests {
		t.Run(name, func(t *testing.T) {
			dbMock.SetCarVersionsLog(tt.carVersionsDB)

			p := httprouter.Params{
				{Key: "vin", Value: tt.vin},
			}

			ctx := context.WithValue(context.Background(), httprouter.ParamsKey, p)
			r := th.MakeTestRequest(http.MethodGet, "http://example.com/vehicle/vin/version/logs?"+tt.query, nil).
				WithContext(ctx)
			w := httptest.NewRecorder()
			handlers.HandleVersionLogsGet(w, r)
			assert.Equal(t, tt.expStatus, w.Code)
			assert.Equal(t, tt.expBody, w.Body.String())
		})
	}
}
