package testdata

import (
	"context"
	"fmt"
	"os"
	"strconv"

	"github.com/docker/docker/api/types/container"
	"github.com/testcontainers/testcontainers-go"
	"github.com/testcontainers/testcontainers-go/modules/mysql"
)

// StartMysqlContainer starts a mysql container for testing.
func StartMysqlContainer(
	ctx context.Context,
	dbName, user, passwd string,
) (c *mysql.MySQLContainer, host string, port uint16, err error) {
	// Refer to https://golang.testcontainers.org/features/garbage_collector/#ryuk.
	if err := os.Setenv("TESTCONTAINERS_RYUK_DISABLED", "true"); err != nil {
		_, _ = fmt.Fprintln(os.Stderr, err)
		return nil, "", 0, err
	}
	mysqlContainer, err := mysql.RunContainer(
		ctx,
		testcontainers.WithImage("gcr.io/pingcap-public/third-party/mysql:8.0"),
		mysql.WithDatabase(dbName),
		mysql.WithUsername(user),
		mysql.WithPassword(passwd),
		testcontainers.WithHostConfigModifier(func(hostConfig *container.HostConfig) {
			hostConfig.Tmpfs = map[string]string{"/var/lib/mysql": "rw"} // Use tmpfs to speed up tests.
		}),
	)
	if err != nil {
		return nil, "", 0, err
	}

	host, err = mysqlContainer.Host(ctx)
	if err != nil {
		return nil, "", 0, err
	}
	portS, err := mysqlContainer.MappedPort(ctx, "3306/tcp")
	if err != nil {
		return nil, "", 0, err
	}
	portParsed, err := strconv.ParseUint(portS.Port(), 10, 16)
	if err != nil {
		return nil, "", 0, err
	}

	return mysqlContainer, host, uint16(portParsed), nil
}
