package cli

import (
	"fmt"

	"github.com/spf13/cobra"

	"git.cloudinit.dev/coreci/orca/internal/doctor"
)

var doctorCmd = &cobra.Command{
	Use:   "doctor",
	Short: "Run self-checks on the orca installation",
	Long:  "Verify CA, server cert, expiry, fingerprint, network, and DB. Reports PASS/WARN/FAIL per check.",
	RunE: func(cmd *cobra.Command, args []string) error {
		report := doctor.Run(cmd.Context())
		if jsonOutput {
			return printJSON(report.Checks)
		}
		fmt.Fprint(cmd.OutOrStdout(), report.Print())
		return nil
	},
}

var doctorCertCmd = &cobra.Command{
	Use:   "cert",
	Short: "Run only the cert self-checks",
	RunE: func(cmd *cobra.Command, args []string) error {
		checks := []doctor.Check{
			doctor.CertCA(),
			doctor.CertServer(),
			doctor.CertExpiry(),
			doctor.CertFingerprint(),
		}
		results := make([]doctor.CheckResult, 0, len(checks))
		for _, c := range checks {
			r, msg := c.Run(cmd.Context())
			results = append(results, doctor.CheckResult{Name: c.Name, Result: r, Message: msg})
		}
		if jsonOutput {
			return printJSON(results)
		}
		for _, r := range results {
			fmt.Fprintf(cmd.OutOrStdout(), "%-20s %-5s  %s\n", r.Name, r.Result, r.Message)
		}
		return nil
	},
}

var doctorNetworkCmd = &cobra.Command{
	Use:   "network",
	Short: "Run the network self-check (P02 impl)",
	RunE: func(cmd *cobra.Command, args []string) error {
		c := doctor.Network()
		r, msg := c.Run(cmd.Context())
		fmt.Fprintf(cmd.OutOrStdout(), "%-20s %-5s  %s\n", c.Name, r, msg)
		return nil
	},
}

var doctorDBCmd = &cobra.Command{
	Use:   "db",
	Short: "Run the database self-check (P02 impl)",
	RunE: func(cmd *cobra.Command, args []string) error {
		c := doctor.DB()
		r, msg := c.Run(cmd.Context())
		fmt.Fprintf(cmd.OutOrStdout(), "%-20s %-5s  %s\n", c.Name, r, msg)
		return nil
	},
}

var doctorOSCmd = &cobra.Command{
	Use:   "os",
	Short: "Run the OS detection self-check (v0.6 P03)",
	RunE: func(cmd *cobra.Command, args []string) error {
		c := doctor.OS()
		r, msg := c.Run(cmd.Context())
		if jsonOutput {
			return printJSON(doctor.CheckResult{Name: c.Name, Result: r, Message: msg})
		}
		fmt.Fprintf(cmd.OutOrStdout(), "%-20s %-5s  %s\n", c.Name, r, msg)
		return nil
	},
}

var doctorProxmoxCmd = &cobra.Command{
	Use:   "proxmox",
	Short: "Run the proxmox node reachability self-check (v0.6 P03)",
	RunE: func(cmd *cobra.Command, args []string) error {
		c := doctor.Proxmox()
		r, msg := c.Run(cmd.Context())
		if jsonOutput {
			return printJSON(doctor.CheckResult{Name: c.Name, Result: r, Message: msg})
		}
		fmt.Fprintf(cmd.OutOrStdout(), "%-20s %-5s  %s\n", c.Name, r, msg)
		return nil
	},
}

func init() {
	doctorCmd.AddCommand(doctorCertCmd, doctorNetworkCmd, doctorDBCmd, doctorOSCmd, doctorProxmoxCmd, noOrcaOnServerCmd, doctorNftCmd)
	rootCmd.AddCommand(doctorCmd)
}
