package app

import (
	"go.uber.org/zap"

	"github.com/helmfile/helmfile/pkg/agent/llm"
)

type ConfigProvider interface {
	Args() string
	HelmBinary() string
	KustomizeBinary() string
	EnableLiveOutput() bool
	StripArgsValuesOnExitError() bool
	DisableForceUpdate() bool
	EnforcePluginVerification() bool
	HelmOCIPlainHTTP() bool
	RepoRetry() int
	SkipDeps() bool
	SkipRefresh() bool
	SequentialHelmfiles() bool

	FileOrDir() string
	KubeContext() string
	Namespace() string
	Chart() string
	Selectors() []string
	StateValuesSet() map[string]any
	StateValuesFiles() []string
	Kubeconfig() string
	Env() string

	loggingConfig
}

type DepsConfigProvider interface {
	Args() string
	SkipRepos() bool
	IncludeTransitiveNeeds() bool

	concurrencyConfig
}

type ReposConfigProvider interface {
	Args() string
	IncludeTransitiveNeeds() bool
}

type ApplyConfigProvider interface {
	Args() string
	PostRenderer() string
	PostRendererArgs() []string
	SkipSchemaValidation() bool
	Cascade() string
	HideNotes() bool
	TakeOwnership() bool
	ServerSide() string
	SuppressOutputLineRegex() []string

	Values() []string
	Set() []string
	SkipCRDs() bool
	SkipDeps() bool
	SkipRefresh() bool
	Wait() bool
	WaitRetries() int
	WaitForJobs() bool
	Timeout() int

	IncludeTests() bool

	Suppress() []string
	SuppressSecrets() bool
	ShowSecrets() bool
	NoHooks() bool
	SuppressDiff() bool

	DetailedExitcode() bool
	StripTrailingCR() bool

	Color() bool
	NoColor() bool
	Context() int
	DiffOutput() string

	Validate() bool
	SkipCleanup() bool
	SkipDiffOnInstall() bool
	SkipDiffValidationOnInstall() bool

	DiffArgs() string
	SyncArgs() string
	TemplateArgs() string

	SyncReleaseLabels() bool

	DAGConfig

	TrackMode() string
	TrackTimeout() int
	TrackLogs() bool
	TrackFailedLogs() bool
	HelmStuckGrace() int
	TrackFailOnError() bool

	Description() string

	concurrencyConfig
	interactive
	loggingConfig
	valuesControlMode
}

type SyncConfigProvider interface {
	Args() string
	PostRenderer() string
	SkipSchemaValidation() bool
	PostRendererArgs() []string
	HideNotes() bool
	TakeOwnership() bool
	ServerSide() string
	Cascade() string

	Values() []string
	Set() []string
	SkipCRDs() bool
	SkipDeps() bool
	SkipRefresh() bool
	Wait() bool
	WaitRetries() int
	WaitForJobs() bool
	Timeout() int
	SyncArgs() string

	Validate() bool

	SkipNeeds() bool
	IncludeNeeds() bool
	IncludeTransitiveNeeds() bool

	SyncReleaseLabels() bool
	TrackMode() string
	TrackTimeout() int
	TrackLogs() bool
	TrackFailedLogs() bool
	HelmStuckGrace() int
	TrackFailOnError() bool

	Color() bool
	NoColor() bool

	Description() string

	TemplateArgs() string

	DAGConfig

	concurrencyConfig
	interactive
	loggingConfig
	valuesControlMode
}

type DiffConfigProvider interface {
	Args() string
	PostRenderer() string
	PostRendererArgs() []string
	SkipSchemaValidation() bool
	SuppressOutputLineRegex() []string

	Values() []string
	Set() []string
	Validate() bool
	SkipCRDs() bool
	SkipDeps() bool
	SkipRefresh() bool

	IncludeTests() bool

	Suppress() []string
	SuppressSecrets() bool
	ShowSecrets() bool
	NoHooks() bool
	SuppressDiff() bool
	SkipDiffOnInstall() bool
	SkipDiffValidationOnInstall() bool
	DiffArgs() string
	TemplateArgs() string

	DAGConfig

	DetailedExitcode() bool
	StripTrailingCR() bool
	Color() bool
	NoColor() bool
	Context() int
	DiffOutput() string
	TakeOwnership() bool
	ServerSide() string

	concurrencyConfig
	valuesControlMode
}

// DoctorConfigProvider is the configuration surface required by App.Doctor.
// It embeds DiffConfigProvider because doctor is a strict superset of diff:
// the same helm-diff flags plus a handful of AI-specific knobs.
//
// The LLM-related accessors return the flag-sourced config only; env and
// helmfile.yaml sources are resolved by the doctor package itself
// (see pkg/agent/doctor/config.go).
type DoctorConfigProvider interface {
	DiffConfigProvider

	// FlagLLMConfig returns the LLM configuration sourced from --llm-* flags.
	// Empty fields mean "flag not set" and do not override env/yaml.
	FlagLLMConfig() llm.Config

	// Force skips the high-risk exit-code-2 gate.
	Force() bool

	// DoctorOutput returns the report format ("text" or "json"). Named
	// DoctorOutput to avoid colliding with DiffConfigProvider.DiffOutput
	// which is the helm-diff plugin output format.
	DoctorOutput() string
}

type DestroyConfigProvider interface {
	Args() string
	Cascade() string

	SkipDeps() bool
	SkipRefresh() bool
	SkipCharts() bool
	DeleteWait() bool
	DeleteTimeout() int
	NoColor() bool

	interactive
	loggingConfig
	concurrencyConfig
}

type TestConfigProvider interface {
	Args() string

	SkipDeps() bool
	SkipRefresh() bool
	Timeout() int
	Cleanup() bool
	Logs() bool

	concurrencyConfig
}

type LintConfigProvider interface {
	Args() string

	Values() []string
	Set() []string
	SkipDeps() bool
	SkipRefresh() bool
	SkipCleanup() bool

	DAGConfig

	concurrencyConfig
}

type UnittestConfigProvider interface {
	Args() string

	Values() []string
	Set() []string
	FailFast() bool
	Color() bool
	DebugPlugin() bool
	SkipDeps() bool
	SkipRefresh() bool
	SkipCleanup() bool

	DAGConfig

	concurrencyConfig
}

type FetchConfigProvider interface {
	SkipDeps() bool
	SkipRefresh() bool
	OutputDir() string
	OutputDirTemplate() string
	WriteOutput() bool

	concurrencyConfig
}

type TemplateConfigProvider interface {
	Args() string
	PostRenderer() string
	PostRendererArgs() []string
	SkipSchemaValidation() bool

	Values() []string
	Set() []string
	OutputDirTemplate() string
	Validate() bool
	SkipDeps() bool
	SkipRefresh() bool
	SkipCleanup() bool
	SkipTests() bool
	OutputDir() string
	IncludeCRDs() bool
	NoHooks() bool
	KubeVersion() string
	ShowOnly() []string
	TemplateArgs() string

	DAGConfig

	concurrencyConfig
}

type DAGConfig interface {
	SkipNeeds() bool
	IncludeNeeds() bool
	IncludeTransitiveNeeds() bool
	EnforceNeedsAreInstalled() bool
}

type WriteValuesConfigProvider interface {
	Values() []string
	Set() []string
	OutputFileTemplate() string
	SkipDeps() bool
	SkipRefresh() bool
	SkipCleanup() bool
	IncludeTransitiveNeeds() bool

	concurrencyConfig
}

type StatusesConfigProvider interface {
	Args() string

	concurrencyConfig
}

type StateConfigProvider interface {
	EmbedValues() bool
}

type DAGConfigProvider any

type concurrencyConfig interface {
	Concurrency() int
}

type loggingConfig interface {
	Logger() *zap.SugaredLogger
}

type interactive interface {
	Interactive() bool
}

type ListConfigProvider interface {
	Output() string
	SkipCharts() bool
}

type CacheConfigProvider any

type InitConfigProvider interface {
	Force() bool
}

type CreateConfigProvider interface {
	Name() string
	OutputDir() string
	Force() bool

	loggingConfig
}

type PrintEnvConfigProvider interface {
	Output() string
}

// reset/reuse values helm cli flags handling for apply/sync/diff
type valuesControlMode interface {
	ReuseValues() bool
	ResetValues() bool
}
