package oauth2

import (
	"context"
	"go.uber.org/zap"
	"gorm.io/gorm"

	"github.com/tidbcloud/auth-server/commons/crypto"
	"github.com/tidbcloud/auth-server/commons/errs"
	"github.com/tidbcloud/auth-server/internal/entity"
	"github.com/tidbcloud/auth-server/internal/repository"
	tierrs "github.com/tidbcloud/tiinf/errs"
	"github.com/tidbcloud/tiinf/monitor/tilog"
)

// Return the access_token identity info by raw access_token
// Provide for the RBAC sdk
func (o *Oauth2ServiceImpl) GetAccessTokenIdentity(ctx context.Context, rawAccessToken string) (*entity.Oauth2AccessToken, tierrs.Error) {
	passwordEncryptor := crypto.NewPbdkf2Sha512Encryptor()
	encryptedToken := passwordEncryptor.Encrypt(rawAccessToken, tokenEncryptSalt, tokenEncryptInterations)

	db := o.db.WithContext(ctx)
	akObj, err := repository.GetOauth2AccessTokenByAccessToken(ctx, db, encryptedToken)
	if err == gorm.ErrRecordNotFound {
		tilog.Info(ctx, "not found AccessToken in db ", zap.Any("rawAccessToken", rawAccessToken))
		return nil, tierrs.NewNotFound("access_token is invalid", nil)
	}

	if err != nil {
		tilog.Error(ctx, "GetAccessTokenIdentity failed", zap.Error(err))
		return nil, errs.WrapGORMError(err, "failed to get access_token row by raw_access_token")
	}

	if isAccessTokenExpired(akObj) {
		tilog.Info(ctx, "access_token is expired")
		return nil, tierrs.NewNotFound("access_token is expired", nil)
	}

	return akObj, nil
}
