package db

import (
	"context"
	"fmt"

	"github.com/tidbcloud/controlplane9/internal/config"
)

const (
	// localMySQLPort is the default MySQL service port for the local MySQL StatefulSet in k3d.
	localMySQLPort = 3306
	// localMySQLHost is the k8s internal DNS name for the MySQL service.
	localMySQLHost = "mysql.default.svc.cluster.local"
	// localMySQLUser is the default MySQL root user.
	localMySQLUser = "root"
)

// LocalMySQLProvider provisions a MySQL 8.0 instance inside the k3d cluster.
// It is an explicit metadb provider choice with no TiDB-compatibility guarantees.
type LocalMySQLProvider struct {
	// Host overrides the default MySQL host (for testing).
	Host string
	// Port overrides the default MySQL port (for testing).
	Port int
}

// Name returns the provider identifier.
func (l *LocalMySQLProvider) Name() config.DatabaseProvider {
	return config.DBLocalMySQL
}

// Provision returns connection details for the local MySQL instance.
// The actual MySQL StatefulSet is deployed by the k3d cluster lifecycle (cp9 up),
// not by this provider. This method only returns the expected connection details.
func (l *LocalMySQLProvider) Provision(_ context.Context) (*Instance, error) {
	host := localMySQLHost
	if l.Host != "" {
		host = l.Host
	}
	port := localMySQLPort
	if l.Port != 0 {
		port = l.Port
	}

	return &Instance{
		Provider: config.DBLocalMySQL,
		ID:       "local-mysql",
		Host:     host,
		Port:     port,
		User:     localMySQLUser,
		Password: "",
	}, nil
}

// CreateDatabase creates a named database within the local MySQL instance
// using the MySQL wire protocol.
func (l *LocalMySQLProvider) CreateDatabase(ctx context.Context, inst *Instance, dbName string) error {
	return createDatabaseMySQL(ctx, inst, dbName)
}

// Destroy is a no-op for local MySQL — the k3d cluster deletion handles cleanup.
func (l *LocalMySQLProvider) Destroy(_ context.Context, _ *Instance) error {
	return nil
}

// LocalMySQLManifest returns the Kubernetes YAML manifest for deploying
// MySQL 8.0 as a StatefulSet in the k3d cluster.
func LocalMySQLManifest() string {
	return fmt.Sprintf(`apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
  - port: %d
    targetPort: %d
  selector:
    app: mysql
  clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        ports:
        - containerPort: %d
        env:
        - name: MYSQL_ALLOW_EMPTY_PASSWORD
          value: "yes"
        readinessProbe:
          exec:
            command: ["mysqladmin", "ping", "-h", "127.0.0.1"]
          initialDelaySeconds: 5
          periodSeconds: 5
`, localMySQLPort, localMySQLPort, localMySQLPort)
}
