package cli

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

func runCertArgs(t *testing.T, args []string) (string, error) {
	t.Helper()
	var buf bytes.Buffer
	rootCmd.SetOut(&buf)
	rootCmd.SetErr(&buf)
	rootCmd.SetArgs(args)
	defer func() {
		rootCmd.SetArgs(nil)
		rootCmd.SetOut(os.Stdout)
		rootCmd.SetErr(os.Stderr)
	}()
	err := rootCmd.Execute()
	return buf.String(), err
}

func TestCertSmoke(t *testing.T) {
	t.Setenv("ORCA_HOME", t.TempDir())

	t.Run("ca-init", func(t *testing.T) {
		out, err := runCertArgs(t, []string{"cert", "ca-init", "--cn", "test-ca"})
		if err != nil {
			t.Fatalf("ca-init: %v\n%s", err, out)
		}
		if !strings.Contains(out, "CA initialized") {
			t.Errorf("ca-init output unexpected: %s", out)
		}
	})

	t.Run("gen", func(t *testing.T) {
		out, err := runCertArgs(t, []string{"cert", "gen", "--cn", "test-server", "--san", "localhost", "--san", "127.0.0.1"})
		if err != nil {
			t.Fatalf("gen: %v\n%s", err, out)
		}
		if !strings.Contains(out, "Server cert generated") {
			t.Errorf("gen output unexpected: %s", out)
		}
	})

	t.Run("show", func(t *testing.T) {
		out, err := runCertArgs(t, []string{"cert", "show"})
		if err != nil {
			t.Fatalf("show: %v\n%s", err, out)
		}
		if strings.Contains(out, "PRIVATE KEY") {
			t.Errorf("show leaked private key material (REQ-035):\n%s", out)
		}
	})

	t.Run("fingerprint_ca", func(t *testing.T) {
		out, err := runCertArgs(t, []string{"cert", "fingerprint", "--which", "ca"})
		if err != nil {
			t.Fatalf("fingerprint ca: %v\n%s", err, out)
		}
		fp := strings.TrimSpace(out)
		if len(fp) != 64 || !isHex(fp) {
			t.Errorf("ca fingerprint = %q, want 64 hex chars", fp)
		}
	})

	t.Run("fingerprint_server", func(t *testing.T) {
		out, err := runCertArgs(t, []string{"cert", "fingerprint", "--which", "server"})
		if err != nil {
			t.Fatalf("fingerprint server: %v\n%s", err, out)
		}
		fp := strings.TrimSpace(out)
		if len(fp) != 64 || !isHex(fp) {
			t.Errorf("server fingerprint = %q, want 64 hex chars", fp)
		}
	})

	t.Run("renew", func(t *testing.T) {
		out, err := runCertArgs(t, []string{"cert", "renew"})
		if err != nil {
			t.Fatalf("renew: %v\n%s", err, out)
		}
		if !strings.Contains(out, "rotated") {
			t.Errorf("renew output unexpected: %s", out)
		}
	})

	t.Run("file_modes", func(t *testing.T) {
		dir := os.Getenv("ORCA_HOME")
		checks := []struct {
			path string
			want os.FileMode
		}{
			{"ca.crt", 0o644},
			{"ca.key", 0o600},
			{"server.crt", 0o644},
			{"server.key", 0o600},
		}
		for _, c := range checks {
			info, err := os.Stat(filepath.Join(dir, c.path))
			if err != nil {
				t.Fatalf("stat %s: %v", c.path, err)
			}
			if got := info.Mode().Perm(); got != c.want {
				t.Errorf("mode %s = %04o, want %04o (REQ-033)", c.path, got, c.want)
			}
		}
	})
}

func isHex(s string) bool {
	for _, r := range s {
		if !((r >= '0' && r <= '9') || (r >= 'a' && r <= 'f') || (r >= 'A' && r <= 'F')) {
			return false
		}
	}
	return true
}
