package data

import (
	"database/sql"
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"time"
	"voucher/internal/conf"
)

type GormDb struct {
	Client *gorm.DB
}

func NewGormDb(c *conf.Bootstrap) (*GormDb, func()) {
	db1, mf := db(c.Data.Db)
	cleanup := func() {
		mf()
	}
	return &GormDb{
		Client: db1,
	}, cleanup
}

func db(data *conf.Data_Database) (*gorm.DB, func()) {
	mysqlConn, err := sql.Open(data.Driver, data.Source)

	gormDB, err := gorm.Open(
		mysql.New(mysql.Config{Conn: mysqlConn}),
		&gorm.Config{Logger: logger.Default.LogMode(logger.Info)},
	)

	if err != nil {
		panic("failed to connect database " + err.Error())
	}

	sqlDB, err := gormDB.DB()
	if err != nil {
		panic("failed to gormDB " + err.Error())
	}

	// SetMaxIdleConns sets the maximum number of connections in the idle connection pool.
	sqlDB.SetMaxIdleConns(int(data.MaxIdle))
	// SetMaxOpenConns sets the maximum number of openapi connections to the database.
	sqlDB.SetMaxOpenConns(int(data.MaxOpen))
	// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
	sqlDB.SetConnMaxLifetime(time.Hour)

	return gormDB, func() {
		if mysqlConn != nil {
			fmt.Println("关闭 db")
			if err := mysqlConn.Close(); err != nil {
				fmt.Printf("关闭 db 失败：%v", err)
			}
		}
	}
}
