package db

import (
	"context"
	"fmt"
	"time"

	"github.com/pingcap/log"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

type loggerAdapter struct {
	enableTrace             bool
	level                   logger.LogLevel
	ignoreRecordNotFoundErr bool
}

func (l *loggerAdapter) LogMode(level logger.LogLevel) logger.Interface {
	l.level = level
	return l
}

func (l *loggerAdapter) Info(_ context.Context, format string, args ...any) {
	if l.level < logger.Info {
		return
	}
	log.L().Info(fmt.Sprintf(format, args...))
}

func (l *loggerAdapter) Warn(_ context.Context, format string, args ...any) {
	if l.level < logger.Warn {
		return
	}
	log.L().Warn(fmt.Sprintf(format, args...))
}

func (l *loggerAdapter) Error(_ context.Context, format string, args ...any) {
	if l.level < logger.Error {
		return
	}
	log.L().Error(fmt.Sprintf(format, args...))
}

func (l *loggerAdapter) Trace(_ context.Context, _ time.Time, fc func() (string, int64), err error) {
	if l.enableTrace || err != nil {
		sql, _ := fc()
		if err != nil {
			if err == gorm.ErrRecordNotFound && !l.ignoreRecordNotFoundErr {
				log.L().Info("GORM Trace", zap.String("SQL", sql))
			} else if err != gorm.ErrRecordNotFound {
				log.L().Error("GORM Trace", zap.String("SQL", sql), zap.Error(err))
			}
		} else {
			log.L().Info("GORM Trace", zap.String("SQL", sql), zap.Error(err))
		}
	}
}
