package cmd

import (
	"os"

	"github.com/innerr/ticat/pkg/core/model"

	"github.com/tidbcloud/controlplane9/internal/config"
	"github.com/tidbcloud/controlplane9/internal/doctor"
	cp9errors "github.com/tidbcloud/controlplane9/internal/errors"
	"github.com/tidbcloud/controlplane9/internal/host"
)

var doctorRunner = doctor.Run

// doctorCmd runs pre-flight checks and environment health validation.
func doctorCmd() model.NormalCmd {
	return func(args model.ArgVals, cc *model.Cli, env *model.Env, _ []model.ParsedCmd) error {
		syncVerbose(env)

		cfgPath := args.GetRaw("config")
		localPath, localProvided := explicitLocalPath(args)

		version, err := config.DetectAPIVersion(cfgPath)
		if err != nil {
			return err
		}
		if version == config.APIVersionV1Alpha2 {
			if err := rejectV1Alpha2LocalConfigOverride(localPath, localProvided); err != nil {
				return err
			}
			session, err := config.LoadSession(cfgPath)
			if err != nil {
				return err
			}
			resolved, err := config.ResolveSession(session, cfgPath)
			if err != nil {
				return err
			}
			selected := host.ResolveSessionConfig(session)
			if loaded, err := host.Load(selected.StateDir); err == nil {
				selected = loaded
			} else if !os.IsNotExist(err) {
				return cp9errors.Newf(cp9errors.CategoryResource, "load selected host: %v", err)
			}
			return outputDoctorResult(cc, env, doctorRunner(&doctor.Options{
				AWSProfile:     resolved.Target.AWS.IAM.Profile,
				Session:        resolved,
				OwnerAllowlist: resolved.CI.OwnerAllowlist,
				Host:           selected,
				StateDir:       selected.StateDir,
				AllNamespaces:  config.SessionPersona(resolved) == "dev-full",
			}))
		}

		cfg, local, err := config.Load(cfgPath, localPath)
		if err != nil {
			return err
		}
		selected, err := host.LoadOrResolve(cfg, local)
		if err != nil {
			return cp9errors.Newf(cp9errors.CategoryResource, "load selected host: %v", err)
		}

		return outputDoctorResult(cc, env, doctorRunner(&doctor.Options{
			AWSProfile:     cfg.Clouds.AWS.Profile,
			OwnerAllowlist: cfg.CI.OwnerAllowlist,
			Host:           selected,
			StateDir:       selected.StateDir,
		}))
	}
}

func outputDoctorResult(cc *model.Cli, env *model.Env, result *doctor.Result) error {
	if err := model.Output(cc, env, result); err != nil {
		return err
	}

	switch result.ExitCode() {
	case 1:
		return cp9errors.New(cp9errors.CategoryConfig, "doctor found warnings")
	case 2:
		return cp9errors.New(cp9errors.CategoryPermanent, "doctor found failures")
	default:
		return nil
	}
}
