package infra

import "fmt"

// SetupVPSApp orquesta el setup inicial de una app en un VPS remoto.
// Pasos: verificar SSH → crear dirs/usuario → rsync código → generar unit → instalar systemd → health check.
func SetupVPSApp(conn SSHConn, cfg DeployConfig) error {
	// 1. Verificar conectividad SSH
	if err := SSHCheck(conn); err != nil {
		return fmt.Errorf("setup_vps_app: ssh check: %w", err)
	}

	// 2. Preparar directorios y usuario en el VPS
	if err := VPSSetupApp(conn, cfg.AppName, cfg.RemoteDir, cfg.ServiceUser); err != nil {
		return fmt.Errorf("setup_vps_app: vps setup: %w", err)
	}

	// 3. Subir binario o archivos de la app
	if err := uploadAppFiles(conn, cfg); err != nil {
		return fmt.Errorf("setup_vps_app: upload: %w", err)
	}

	// 4. Generar unit de systemd
	execStart := fmt.Sprintf("%s/%s", cfg.RemoteDir, cfg.BinaryName)
	unit := SystemdGenerateUnit(cfg.AppName, execStart, cfg.RemoteDir, cfg.ServiceUser, cfg.Env)

	// 5. Instalar y arrancar servicio
	if err := SystemdInstall(conn, cfg.AppName, unit); err != nil {
		return fmt.Errorf("setup_vps_app: systemd install: %w", err)
	}

	// 6. Health check (si hay endpoint configurado)
	if cfg.HealthPath != "" && cfg.Port > 0 {
		url := fmt.Sprintf("http://%s:%d%s", conn.Host, cfg.Port, cfg.HealthPath)
		if err := HealthCheckHTTP(url, 30, 2000); err != nil {
			return fmt.Errorf("setup_vps_app: health check: %w", err)
		}
	}

	return nil
}

// uploadAppFiles sube el binario compilado al VPS via SCP.
func uploadAppFiles(conn SSHConn, cfg DeployConfig) error {
	localBinary := fmt.Sprintf("%s/%s", cfg.LocalDir, cfg.BinaryName)
	remoteBinary := fmt.Sprintf("%s/%s", cfg.RemoteDir, cfg.BinaryName)

	if err := SSHUpload(conn, localBinary, remoteBinary); err != nil {
		return err
	}

	// Hacer ejecutable
	_, stderr, code, err := SSHExec(conn, fmt.Sprintf("chmod +x %s", remoteBinary))
	if err != nil {
		return err
	}
	if code != 0 {
		return fmt.Errorf("chmod: %s", stderr)
	}
	return nil
}
