package migrate

import (
	"context"
	"database/sql"
	"fmt"
	"log"
	"strings"

	_ "github.com/go-sql-driver/mysql" // MySQL driver registration.
)

// ApplyDump applies a SQL dump to the local database.
func ApplyDump(ctx context.Context, dsn string, dump []byte) error {
	if len(dump) == 0 {
		return nil
	}

	// Append multiStatements parameter, using ? or & depending on existing query string.
	sep := "?"
	if strings.Contains(dsn, "?") {
		sep = "&"
	}
	conn, err := sql.Open("mysql", dsn+sep+"multiStatements=true")
	if err != nil {
		return fmt.Errorf("open connection: %w", err)
	}
	defer conn.Close()

	if _, err := conn.ExecContext(ctx, string(dump)); err != nil {
		return fmt.Errorf("apply dump: %w", err)
	}
	return nil
}

// ResetDatabase drops and recreates a database.
func ResetDatabase(ctx context.Context, adminDSN, dbName string) error {
	conn, err := sql.Open("mysql", adminDSN)
	if err != nil {
		return fmt.Errorf("open admin connection: %w", err)
	}
	defer conn.Close()

	log.Printf("migrate: dropping database %s", dbName)
	stmt := fmt.Sprintf("DROP DATABASE IF EXISTS `%s`", dbName)
	if _, err := conn.ExecContext(ctx, stmt); err != nil {
		return fmt.Errorf("drop database %q: %w", dbName, err)
	}

	stmt = fmt.Sprintf("CREATE DATABASE `%s`", dbName)
	if _, err := conn.ExecContext(ctx, stmt); err != nil {
		return fmt.Errorf("recreate database %q: %w", dbName, err)
	}

	return nil
}
