package mysql

import (
	"context"
	"database/sql"
	"errors"
	"fmt"
	"sync"
	"time"
)

func CheckConn(ctx context.Context, dsn string, tlsConfig *TLSConfig, timeout time.Duration) error {
	ctx, cancel := withTimeout(ctx, timeout)
	defer cancel()

	db, err := newDB(dsn, tlsConfig)
	if err != nil {
		return err
	}
	defer db.Close()

	wg := sync.WaitGroup{}
	errList := []error{}
	for i := 0; i < 10; i++ {
		conn, err := db.Conn(ctx)
		if err != nil {
			return err
		}

		wg.Add(1)

		go func(conn *sql.Conn) {
			defer wg.Done()
			for {
				if err := conn.PingContext(ctx); err != nil {
					if !errors.Is(err, context.Canceled) || !errors.Is(err, context.DeadlineExceeded) {
						errList = append(errList, err)
					}
					conn.Close()
					cancel()
					break
				}
				time.Sleep(time.Second * 10)
			}

		}(conn)
	}

	wg.Wait()

	if len(errList) != 0 {
		return fmt.Errorf("connection cannot keep: %v", errList)
	}

	return nil
}

func withTimeout(ctx context.Context, timeout time.Duration) (context.Context, context.CancelFunc) {
	if timeout == 0 {
		return context.WithCancel(ctx)
	}

	return context.WithTimeout(ctx, timeout)
}
