package sample_data

import (
	"fmt"

	"github.com/tidbcloud/dataflow-service-e2e/internal/log"
	"github.com/tidbcloud/dataflow-service-e2e/internal/misc"
)

type MySQLParameter struct {
	Endpoint   string
	User       string
	Password   string
	TLSEnabled bool
}

type MySQLDownstreamManager struct {
	lgr    log.SimpleLogger
	params *MySQLParameter
	dbName string
}

func NewMySQLDownstreamManager(lgr log.SimpleLogger, params *MySQLParameter, dbName string) *MySQLDownstreamManager {
	return &MySQLDownstreamManager{
		lgr:    lgr,
		params: params,
		dbName: dbName,
	}
}

func (m *MySQLDownstreamManager) InitTables() error {
	db, err := Connect2MySQL(m.params.User, m.params.Password, m.params.Endpoint, "", m.params.TLSEnabled)
	if err != nil {
		m.lgr.Error("connect to mysql downstream failed, error: %s, mysql: %s", err.Error(), misc.JSON(m.params))
		return fmt.Errorf("connect to mysql downstream error: %w", err)
	}

	// Create database if not exists
	_, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", m.dbName))
	if err != nil {
		m.lgr.Error("create database failed, dbName: %s, error: %s, mysql: %s", m.dbName, err.Error(), misc.JSON(m.params))
		return fmt.Errorf("create database error: %w", err)
	}

	m.lgr.Info("database '%s' in mysql downstream is ready!", m.dbName)

	err = db.Close()
	if err != nil {
		m.lgr.Warn("close db connection failed after database created, error: %s, mysql: %s", err.Error(), misc.JSON(m.params))
	}

	db, err = Connect2MySQL(m.params.User, m.params.Password, m.params.Endpoint, m.dbName, m.params.TLSEnabled)
	if err != nil {
		m.lgr.Error("connect to mysql downstream with database(%s) failed, error: %s, mysql: %s", m.dbName, err.Error(), misc.JSON(m.params))
		return fmt.Errorf("connect to mysql downstream with database error: %w", err)
	}
	defer db.Close()

	// Ensure table exists
	_, err = db.Exec(fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s (
		id INT AUTO_INCREMENT PRIMARY KEY,
		created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
	);`, SAMPLE_TABLE))
	if err != nil {
		m.lgr.Error("create table '%s' failed, error: %s, mysql: %s", SAMPLE_TABLE, err.Error(), misc.JSON(m.params))
		return fmt.Errorf("create table '%s' error: %w", SAMPLE_TABLE, err)
	}
	return nil
}

func (m *MySQLDownstreamManager) DropTables() error {
	db, err := Connect2MySQL(m.params.User, m.params.Password, m.params.Endpoint, "", m.params.TLSEnabled)
	if err != nil {
		m.lgr.Error("connect to mysql downstream failed, error: %s, mysql: %s", err.Error(), misc.JSON(m.params))
		return fmt.Errorf("connect to mysql downstream error: %w", err)
	}
	defer db.Close()

	_, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", m.dbName))
	if err != nil {
		m.lgr.Error("drop database failed, dbName: %s, error: %s, mysql: %s", m.dbName, err.Error(), misc.JSON(m.params))
		return fmt.Errorf("drop database error: %w", err)
	}

	m.lgr.Info("database '%s' in mysql downstream is dropped", m.dbName)
	return nil
}
