package handlers_test

import (
	"context"
	"github.com/fiskerinc/cloud-services/pkg/clickhouse"
	"github.com/fiskerinc/cloud-services/pkg/common"
	"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
	"github.com/julienschmidt/httprouter"
	"github.com/stretchr/testify/assert"
	"net/http"
	"net/http/httptest"
	"otaupdate/handlers"
	"otaupdate/services"
	"testing"
)

func TestHandleDBCSignalsGetList(t *testing.T) {
	validQuery := "?limit=5&offset=2"
	tests := map[string]struct {
		q         string
		conn      clickhouse.ConnInterface
		expStatus int
		expBody   string
	}{
		"correct": {
			q: validQuery,
			conn: &clickhouse.MockConn{
				ExpectedResult: []common.SignalDescWithECU{
					{
						ECUName: "ADAS",
						SignalDesc: common.SignalDesc{
							DBCHash:           "hash",
							MessageID:         2,
							Name:              "All_Signals_Sum_Check0",
							Start:             0,
							Length:            8,
							IsBigEndian:       true,
							IsSigned:          true,
							IsMultiplexer:     true,
							IsMultiplexed:     false,
							MultiplexerValue:  5,
							Offset:            0,
							Scale:             3,
							Min:               0,
							Max:               20,
							Unit:              "sm",
							Description:       "desc",
							ValueDescriptions: []string{"lt", "lg", "lk"},
							ReceiverNodes:     []string{"GW", "OO"},
							DefaultValue:      0,
						},
					}, {
						ECUName: "ICC",
						SignalDesc: common.SignalDesc{
							DBCHash:           "hash",
							MessageID:         20,
							Name:              "All_Signals_Sum_Check1",
							Start:             8,
							Length:            12,
							IsBigEndian:       false,
							IsSigned:          false,
							IsMultiplexer:     false,
							IsMultiplexed:     true,
							MultiplexerValue:  7,
							Offset:            8,
							Scale:             31,
							Min:               5,
							Max:               12,
							Unit:              "kg",
							Description:       "desc 1",
							ValueDescriptions: nil,
							ReceiverNodes:     nil,
							DefaultValue:      10,
						},
					},
				},
				QueryRowtMock: func(ctx context.Context, query string, args ...interface{}) driver.Row {
					return clickhouse.RowMock{RowResult: 5}
				}},
			expStatus: http.StatusOK,
			expBody:   `{"data":[{"dbc_hash":"hash","message_id":2,"name":"All_Signals_Sum_Check0","start":0,"length":8,"big_endian":true,"signed":true,"multiplexer":true,"multiplexed":false,"multiplexer_value":5,"offset":0,"scale":3,"min":0,"max":20,"unit":"sm","description":"desc","value_descriptions":["lt","lg","lk"],"receiver_nodes":["GW","OO"],"default_value":0,"ECUName":"","ecu_name":"ADAS"},{"dbc_hash":"hash","message_id":20,"name":"All_Signals_Sum_Check1","start":8,"length":12,"big_endian":false,"signed":false,"multiplexer":false,"multiplexed":true,"multiplexer_value":7,"offset":8,"scale":31,"min":5,"max":12,"unit":"kg","description":"desc 1","value_descriptions":null,"receiver_nodes":null,"default_value":10,"ECUName":"","ecu_name":"ICC"}]}`,
		},
		"failed_query": {
			q:         validQuery,
			conn:      &clickhouse.MockConn{ExpectedResult: someErr},
			expStatus: http.StatusServiceUnavailable,
			expBody:   `{"message":"json: cannot unmarshal object into Go value of type []common.SignalDescWithECU","error":"Service Unavailable"}`,
		},
		"wrong limit": {
			q:         "?limit=-2",
			expStatus: http.StatusBadRequest,
			expBody:   `{"message":"Limit less than 0","error":"Bad Request"}`,
		},
	}

	for tname, tt := range tests {
		t.Run(tname, func(t *testing.T) {
			services.SetClickhouseConn(tt.conn)
			w := httptest.NewRecorder()
			p := httprouter.Params{
				{
					Key:   "dbc",
					Value: "hash",
				},
			}
			ctx := context.WithValue(context.Background(), httprouter.ParamsKey, p)
			r := httptest.NewRequest(http.MethodGet, "http://example.com/can_signals/dbc"+tt.q, nil).
				WithContext(ctx)

			handlers.HandleDBCSignalsGetList(w, r)
			assert.Equal(t, tt.expStatus, w.Code)
			assert.Equal(t, tt.expBody, w.Body.String())
		})
	}
}
