package queries_test

import (
	"testing"

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

func TestSubscriptions(t *testing.T) {
	t.Skip()
	query, carToDriver, subtype := setupSubscriptions(t)
	defer cleanUpSubscriptionTest(carToDriver, subtype)
	if query == nil || carToDriver == nil || subtype == nil {
		t.Error("setupSubscriptions error")
		return
	}

	subID := createSubscription(t, query, carToDriver, subtype)
	if subID == 0 {
		return
	}
	selectSubscription(t, query, subID)
	updateSubscription(t, query, subID)
	deleteSubscription(t, query, subID)
}

func setupSubscriptions(t *testing.T) (queries.SubscriptionsInterface, *common.CarToDriver, *common.SubscriptionType) {
	subtype := createTestSubscriptionType(t)
	carToDriver, err := createTestCarDriver(t)
	if err != nil {
		return nil, nil, nil
	}
	instance := &queries.Subscriptions{}
	conn = instance.GetDBConn()
	conn.AddQueryHook(db.SQLLogger{})

	return instance, carToDriver, subtype
}

func createTestSubscriptionType(t *testing.T) *common.SubscriptionType {
	subtypes := setupSubscriptionTypes(t)
	subtype := insertSubscriptionType(t, subtypes)

	return subtype
}

func createTestCarDriver(t *testing.T) (*common.CarToDriver, error) {
	driver := common.Driver{
		ID: uuid.New().String(),
	}
	drivers := queries.Drivers{}
	_, err := drivers.Insert(&driver)
	if err != nil {
		return nil, err
	}

	cars := queries.Cars{}
	car := common.Car{
		VIN: "4S3BJ6332P6953766",
	}
	_, err = cars.Insert(&car)
	if err != nil {
		return nil, err
	}

	carToDriver, err := cars.AddDriver(&car, &driver, "driver")
	if err != nil {
		return nil, err
	}

	return carToDriver, nil
}

func createSubscription(t *testing.T, query queries.SubscriptionsInterface, carToDriver *common.CarToDriver, subtype *common.SubscriptionType) int64 {
	sub, err := query.Create(subtype, carToDriver)
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "Subscription insert", nil, err)
		return 0
	}

	return sub.ID
}

func selectSubscription(t *testing.T, query queries.SubscriptionsInterface, subID int64) {
	sub := common.Subscription{ID: subID}
	err := query.Load(&sub)
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions Load", nil, err)
	}
	if sub.Name == "" {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions Load Name", "not empty", sub.Name)
	}

	subTypeValues := map[string]interface{}{
		"Name":        "NAME",
		"Destination": "ICC",
	}
	testhelper.PropsTester(t, &sub, subTypeValues)

	subtypes, err := query.Select(&common.Subscription{ID: subID})
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions Select", nil, err)
	}
	if len(subtypes) != 1 {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions Select count", 1, len(subtypes))
	} else {
		testhelper.PropsTester(t, &subtypes[0], subTypeValues)
	}

	count, err := query.Count(&common.Subscription{ID: subID})
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions Count", nil, err)
	}
	if count != 1 {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions Count", 1, count)
	}
}

func updateSubscription(t *testing.T, query queries.SubscriptionsInterface, subID int64) {
	sub := common.Subscription{ID: subID}
	err := query.Load(&sub)
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions Update Load", nil, err)
	}

	sub.Name = "NAME2"
	result, err := query.Update(&sub)
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions Update", nil, err)
	} else {
		if result.RowsAffected() != 1 {
			t.Errorf(testhelper.TestErrorTemplate, "Subscriptions Update RowsAffected", 1, result.RowsAffected())
		}
		if result.RowsReturned() != 0 {
			t.Errorf(testhelper.TestErrorTemplate, "Subscriptions Update RowsReturned", 0, result.RowsReturned())
		}
	}

	sub = common.Subscription{ID: subID}
	err = query.Load(&sub)
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions Update Reload", nil, err)
	}
	if sub.Name != "NAME2" {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions Update", "NAME2", sub.Name)
	}
}

func deleteSubscription(t *testing.T, query queries.SubscriptionsInterface, subID int64) {
	result, err := query.Delete(&queries.SubscriptionDeleteRequest{VIN: "4S3BJ6332P6953766", Name: "NAME2"})
	if err != nil {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions delete", nil, err)
		return
	}

	if result.RowsAffected() != 1 {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions delete RowsAffected", 1, result.RowsAffected())
	}

	if result.RowsReturned() != 0 {
		t.Errorf(testhelper.TestErrorTemplate, "Subscriptions delete RowsReturned", 0, result.RowsReturned())
	}
}

func cleanUpSubscriptionTest(carToDriver *common.CarToDriver, subtype *common.SubscriptionType) {
	drivers := queries.Drivers{}
	cars := queries.Cars{}

	cars.RemoveDriver(carToDriver.VIN, carToDriver.DriverID)
	cars.Delete(&common.Car{VIN: carToDriver.VIN})

	drivers.Delete(&common.Driver{ID: carToDriver.DriverID})

	if subtype.ID != uuid.Nil {
		subtypes := queries.SubscriptionTypes{}
		subtypes.Delete(subtype)
	}
}
