package cmd

import (
	"os"
	"path/filepath"
	"strings"
	"testing"
)

func TestSubcommandNoArgsNonInteractiveRunsDirectly(t *testing.T) {
	// Not parallel: mutates package-level isStdinTerminal.

	// Override stdin terminal check to simulate non-interactive environment.
	original := isStdinTerminal
	t.Cleanup(func() {
		isStdinTerminal = original
	})
	isStdinTerminal = func() bool { return false }

	// Create a config with backup paths defined so the command can run.
	configFile := setupConfigWithBackupPaths(t)
	setRootFlagValuesForTest(t, "home@cloud", true, configFile)
	t.Setenv("KELD_CONFIG_FILE", "")
	t.Setenv("KELD_DRYRUN", "")

	backup := lookupSubcommand(t, "backup")
	out, err := captureStdout(t, func() error {
		return backup.RunE(backup, []string{})
	})
	// Should NOT get a bubbletea TTY error. Instead, should either:
	// - Succeed with dry-run output (if config has paths), or
	// - Fail with a sensible error about missing inputs.
	if err != nil {
		errMsg := err.Error()
		// The old bug would produce "bubbletea: error opening TTY" here.
		if strings.Contains(errMsg, "bubbletea") || strings.Contains(errMsg, "TTY") {
			t.Fatalf("non-interactive mode incorrectly tried to open TTY: %v", err)
		}
		// A different error is acceptable (e.g., missing paths).
		// For now we just verify no TTY error occurred.
		t.Logf("command returned error (expected for missing paths): %v", err)
		return
	}

	// If no error, we should see dry-run output.
	if !strings.Contains(out, `"backup"`) {
		t.Fatalf("expected dry-run output to contain backup command, got:\n%s", out)
	}
}

// setupConfigWithBackupPaths creates a config file with a preset that has
// backup paths defined, allowing the backup command to run without args.
func setupConfigWithBackupPaths(t *testing.T) string {
	t.Helper()

	dir := t.TempDir()
	cfg := filepath.Join(dir, "config.toml")
	err := os.WriteFile(cfg, []byte(`
[global]
repo = "/repos/default"

["home@"]
tag = "home"

["home@".backup]
_arguments = "/src /dst"

["@cloud"]
repo = "/repos/cloud"
`), 0o600)
	if err != nil {
		t.Fatalf("writing fixture: %v", err)
	}
	t.Setenv("HOME", dir)

	return cfg
}

func TestSubcommandNoArgsInteractiveEntersSession(t *testing.T) {
	// Not parallel: mutates package-level isStdinTerminal.

	// Override stdin terminal check to simulate interactive terminal.
	original := isStdinTerminal
	t.Cleanup(func() {
		isStdinTerminal = original
	})
	isStdinTerminal = func() bool { return true }

	configFile := setupConfigWithBackupPaths(t)
	setRootFlagValuesForTest(t, "", true, configFile)
	t.Setenv("KELD_CONFIG_FILE", "")
	t.Setenv("KELD_DRYRUN", "")

	backup := lookupSubcommand(t, "backup")

	// In interactive mode with no args, runInteractive is called.
	// Since there's no real TTY attached during test, bubbletea will
	// try to open /dev/tty and fail. We assert this behavior is happening
	// (rather than the command running directly).
	_, err := captureStdout(t, func() error {
		return backup.RunE(backup, []string{})
	})

	// The expected behavior: bubbletea tries to open TTY and fails.
	if err == nil {
		// If it succeeded, either we're not in interactive mode or
		// the test environment has a TTY (unlikely in CI).
		t.Fatal("expected bubbletea TTY error when simulating interactive mode, got success")
	}
	errMsg := err.Error()
	if !strings.Contains(errMsg, "TTY") && !strings.Contains(errMsg, "tty") {
		t.Fatalf("expected bubbletea TTY error in interactive mode, got: %v", err)
	}
}
