package user

import (
	"context"
	"log"
	"os"
	"testing"

	"github.com/smartystreets/goconvey/convey"
	"github.com/tidbcloud/account/internel/dao/entity"
	"github.com/tidbcloud/account/pkg/docker_db"
	"gorm.io/gorm"
)

var db *gorm.DB

func init() {
	var err error
	db, err = docker_db.TryInitCentralDB(true)
	if err != nil {
		log.Printf("Failed to init docker db: %s", err)
		os.Exit(-1)
		return
	}
}

func deleteUserByEmail(email string) {
	db.Where("email = ?", email).Delete(&entity.User{})
}

func ensureCreateUser(t *testing.T, email string) *entity.User {
	ctx := context.TODO()

	d := &UserDao{}
	user := &entity.User{
		FirstName:   "FirstName",
		LastName:    "LastName",
		Email:       email,
		Status:      "active",
		InvitedAt:   nil,
		Job:         "bla",
		PhoneNumber: "+861111111111111",
		Role:        "owner",
	}

	_, err := d.CreateUser(ctx, db, user)
	convey.So(err, convey.ShouldBeNil)
	return user
}

func TestUserDao_CreateUser(t *testing.T) {
	convey.Convey("create user", t, func() {
		convey.Convey("create user success", func() {
			email := "email"
			user := ensureCreateUser(t, email)
			defer deleteUserByEmail(email)

			convey.So(user.ID, convey.ShouldNotBeZeroValue)
		})
	})
}

func TestUserDao_GetUserByID(t *testing.T) {
	d := &UserDao{}
	ctx := context.TODO()

	convey.Convey("load system user", t, func() {
		email := "email"

		user := ensureCreateUser(t, email)
		defer deleteUserByEmail(email)

		convey.Convey("load user by id success", func() {
			newUser, err := d.GetUserByID(ctx, db, user.ID.Uint64())
			convey.So(err, convey.ShouldBeNil)
			convey.So(newUser.PhoneNumber, convey.ShouldEqual, user.PhoneNumber)
		})

		convey.Convey("not found", func() {
			newUser, err := d.GetUserByID(ctx, db, 1008611)
			convey.So(err, convey.ShouldEqual, gorm.ErrRecordNotFound)
			convey.So(newUser, convey.ShouldBeNil)
		})
	})
}

func TestUserDao_ListUsers(t *testing.T) {
	d := &UserDao{}
	ctx := context.TODO()

	convey.Convey("ListUsers", t, func() {
		convey.Convey("no users in db", func() {
			_, err := d.ListUsers(ctx, db, nil, nil)
			convey.So(err, convey.ShouldBeNil)
		})

		convey.Convey("user in db", func() {
			email := "test@pingcap.com"
			user := ensureCreateUser(t, email)
			defer deleteUserByEmail(email)

			convey.Convey("user id match", func() {
				users, err := d.ListUsers(ctx, db, []uint64{user.ID.Uint64()}, nil)
				convey.So(err, convey.ShouldBeNil)
				convey.So(len(users), convey.ShouldEqual, 1)
			})

			convey.Convey("user id not match", func() {
				users, err := d.ListUsers(ctx, db, []uint64{user.ID.Uint64() + 1}, nil)
				convey.So(err, convey.ShouldBeNil)
				convey.So(len(users), convey.ShouldEqual, 0)
			})
		})
	})
}
