package repository

import (
	"context"
	"time"

	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"

	"github.com/tidbcloud/auth-server/internal/entity"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

func CreateOauth2DeviceGrant(ctx context.Context, tx *gorm.DB, obj *entity.Oauth2DeviceGrant) error {
	return obj.Create(tx)
}

func GetOauth2DeviceGrantByDeviceCode(ctx context.Context, tx *gorm.DB, deviceCode string) (*entity.Oauth2DeviceGrant, error) {
	var obj entity.Oauth2DeviceGrant
	err := entity.NewOauth2DeviceGrantQuerySet(tx).DeviceCodeEq(deviceCode).One(&obj)
	return &obj, err
}

func GetOauth2DeviceGrantByDeviceCodeWithLock(ctx context.Context, tx *gorm.DB, deviceCode string) (*entity.Oauth2DeviceGrant, error) {
	var obj entity.Oauth2DeviceGrant
	err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).Where("device_code = ?", deviceCode).First(&obj).Error
	return &obj, err
}

func GetOauth2DeviceGrantByUserCode(ctx context.Context, tx *gorm.DB, userCode string) (*entity.Oauth2DeviceGrant, error) {
	var obj entity.Oauth2DeviceGrant
	err := entity.NewOauth2DeviceGrantQuerySet(tx).UserCodeEq(userCode).One(&obj)
	tilog.Info(ctx, "GetOauth2DeviceGrantByUserCode", zap.Any("Oauth2DeviceGrant", obj))
	return &obj, err
}

func GetOauth2DeviceGrantByUserCodeWithLock(ctx context.Context, tx *gorm.DB, userCode string) (*entity.Oauth2DeviceGrant, error) {
	var obj entity.Oauth2DeviceGrant
	err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).Where("user_code = ?", userCode).First(&obj).Error
	return &obj, err
}

func UpdateOauth2DeviceGrant(ctx context.Context, tx *gorm.DB, obj *entity.Oauth2DeviceGrant, schemas []entity.Oauth2DeviceGrantDBSchemaField) error {
	now := time.Now()
	schemas = append(schemas, entity.Oauth2DeviceGrantDBSchema.UpdatedAt)
	obj.UpdatedAt = &now
	return obj.Update(tx, schemas...)
}
