package common_test

import (
	"testing"
	"time"

	"github.com/fiskerinc/cloud-services/pkg/common"
	"github.com/fiskerinc/cloud-services/pkg/common/dbbasemodel"
	"github.com/fiskerinc/cloud-services/pkg/testhelper"
	"github.com/google/uuid"
)

func TestMobileRXMessages(t *testing.T) {
	schema := "file://" + testhelper.GetSchemaDirPath() + "/mobile/RXMessage.json"
	now := time.Now()

	percent, maxMiles, temp, chTime, stateOfCharge := 100, 350, -11, 43, 40
	typ := "AC"

	tests := []testhelper.SchemaTest{
		{
			Name: "TestMobileCarLocations",
			Object: common.Message{
				Handler: "car_locations",
				Data: []common.JSONCarLocation{
					{
						VIN:       "1F15K3R45N1234567",
						Altitude:  1,
						Latitude:  2,
						Longitude: 3,
					},
					{
						VIN:       "1F15K3R45N3456789",
						Altitude:  100,
						Latitude:  200,
						Longitude: 300,
					},
				},
			},
		},
		{
			Name: "TestMobileDigitalTwin",
			Object: common.Message{
				Handler: "digital_twin",
				Data: common.JSONDigitalTwin{
					VIN:       "1F15K3R45N1234567",
					Online:    true,
					OnlineHMI: true,
					VehicleSpeed: &common.VehicleSpeed{
						Speed: 123.4,
					},
					Battery: &common.JSONBattery{
						Percent:               &percent,
						MaxMiles:              &maxMiles,
						AvgCellTemperature:    &temp,
						ChargeType:            &typ,
						RemainingChargingTime: &chTime,
						StateOfCharge:         &stateOfCharge,
					},
					Doors: &common.Doors{
						LeftFront:  true,
						LeftRear:   true,
						RightFront: false,
						RightRear:  false,
					},
					Location: &common.Location{
						Altitude:  1000,
						Longitude: 1,
						Latitude:  -1,
					},
					Locks: &common.Locks{
						Driver: true,
						All:    false,
					},
					UpdatedAt: &time.Time{},
					Windows: &common.JSONWindows{
						LeftFront:        0,
						LeftRear:         25,
						LeftRearQuarter:  100,
						RightFront:       50,
						RightRear:        75,
						RightRearQuarter: 100,
						RearWindshield:   100,
						Sunroof:          100,
					},
					ClimateControl: &common.JSONClimateControl{
						CabinTemperature:  70,
						RearDefrost:       false,
						DriverSeatHeat:    0,
						PassengerSeatHeat: 0,
						SteeringWheelHeat: false,
					},
				},
			},
		},
		{
			Name: "TestMobileProfiles",
			Object: common.Message{
				Handler: "profiles",
				Data: []common.JSONMobileProfile{
					{
						VIN:        "1F15K3R45N1234567",
						DriverRole: "OWNER",
						Settings: []common.CarSetting{{
							Name:  "TESTSETTING",
							Value: "TESTVALUE",
							Type:  "string",
							DBModelBase: dbbasemodel.DBModelBase{
								UpdatedAt: &now,
							},
						}},
						Subscriptions: []common.Subscription{{
							Name:        "test",
							Destination: "ICC",
							Expires:     time.Date(2021, 10, 30, 8, 35, 0, 0, time.UTC),
						}},
					},
					{
						VIN:        "1F15K3R45N3456789",
						DriverRole: "DRIVER",
					},
				},
			},
		},
		{
			Name: "TestMobileSettingsUpdate",
			Object: common.Message{
				Handler: "settings_update",
				Data: common.MobileSettingsUpdate{
					VIN: "1F15K3R45N1234567",
					Settings: []common.CarSetting{{
						Name:  "TESTSETTING",
						Value: "TESTVALUE",
						Type:  "string",
						DBModelBase: dbbasemodel.DBModelBase{
							UpdatedAt: &now,
						},
					}},
				},
			},
		},
		{
			Name: "TestMobileStoreInventory",
			Object: common.Message{
				Handler: "store_inventory",
				Data: []common.SubscriptionType{{
					ID:            uuid.New(),
					Name:          "TESTSUB",
					Destination:   "ICC",
					Price:         100,
					Currency:      "USD",
					Description:   "this is a test",
					DurationValue: 5,
					DurationUnit:  "Hours",
				}},
			},
		},
		{
			Name: "TestMobileSubscriptionsUpdate",
			Object: common.Message{
				Handler: "subscriptions_update",
				Data: common.MobileSubscriptionUpdate{
					VIN: "1F15K3R45N1234567",
					Subscriptions: []common.Subscription{{
						Name:        "test",
						Destination: "ICC",
						Expires:     time.Date(2021, 10, 30, 8, 35, 0, 0, time.UTC),
					}},
				},
			},
		},
		{
			Name: "TestMobileStorePurchaseError",
			Object: common.Message{
				Handler: "store_purchase_error",
				Data: common.JSONError{
					Error: "test error",
				},
			},
		},
		{
			Name: "TestMobileStoreInventoryError",
			Object: common.Message{
				Handler: "store_inventory_error",
				Data: common.JSONError{
					Error: "test error",
				},
			},
		},
		{
			Name: "TestUpdates",
			Object: common.Message{
				Handler: "updates",
				Data: []common.ApprovalUpdate{
					{
						ID:           1000,
						VIN:          "1F15K3R45N1234567",
						Name:         "Update name",
						Version:      "Update version",
						Description:  "Update description",
						ReleaseNotes: "http://releasenotes.com",
					},
					{
						ID:           1001,
						VIN:          "1F15K3R45N1234567",
						Name:         "Update name",
						Version:      "Update version",
						Description:  "Update description",
						ReleaseNotes: "http://releasenotes.com",
					},
				},
			},
		},
		{
			Name: "TestPOIs",
			Object: common.Message{
				Handler: "user_pois",
				Data: []common.PointOfInterest{
					{
						Name: "TestWorkPOI",
						Location: common.POILocation{
							Latitude:  1.11,
							Longitude: 2.22,
						},
					},
					{
						Name: "TestHomePOI",
						Location: common.POILocation{
							Latitude:  8.88,
							Longitude: 9.99,
						},
					},
				},
			},
		},
		{
			Name: "TestMobileError",
			Object: common.Message{
				Handler: "error",
				Data: common.MessageString{
					Message: "disconnected by duplicate ID",
				},
			},
		},
		{
			Name: "TestMobileManualIssue",
			Object: common.Message{
				Handler: "manual_issue",
				Data: common.AddIssueRequest{
					Issue: common.Issue{
						VIN:         "1F15K3R45N1234567",
						Title:       "HMI not working",
						Description: "Black screen on HMI",
						Timestamp:   time.Now(),
					},
					Images: [][]byte{
						{72, 101, 108, 108, 111},
						{72, 101, 108, 108, 49},
					},
				},
			},
		},
	}

	testhelper.NewSchemaTestHelper(t, schema).
		RunSchemaTests(tests)
}
