package internal

import (
	"os"

	logrusStack "github.com/Gurpartap/logrus-stack"
	"github.com/sirupsen/logrus"
	"github.com/urfave/cli"
)

// Secrets stores the variable from SecretsFlag
var Secrets bool

// SecretsFlag turns on/off automatically generating secrets
var SecretsFlag = &cli.BoolFlag{
	Name:        "secrets, S",
	Usage:       "Automatically generate secrets",
	Destination: &Secrets,
}

// Pass stores the variable from PassFlag
var Pass bool

// PassFlag turns on/off storing generated secrets in pass
var PassFlag = &cli.BoolFlag{
	Name:        "pass, p",
	Usage:       "Store the generated secrets in a local pass store",
	Destination: &Pass,
}

// PassRemove stores the variable for PassRemoveFlag
var PassRemove bool

// PassRemoveFlag turns on/off removing generated secrets from pass
var PassRemoveFlag = &cli.BoolFlag{
	Name:        "pass, p",
	Usage:       "Remove generated secrets from a local pass store",
	Destination: &PassRemove,
}

// Force force functionality without asking.
var Force bool

// ForceFlag turns on/off force functionality.
var ForceFlag = &cli.BoolFlag{
	Name:        "force, f",
	Usage:       "Perform action without further prompt. Use with care!",
	Destination: &Force,
}

// Chaos engages chaos mode.
var Chaos bool

// ChaosFlag turns on/off chaos functionality.
var ChaosFlag = &cli.BoolFlag{
	Name:        "chaos, C",
	Usage:       "Deploy uncommitted recipes changes. Use with care!",
	Destination: &Chaos,
}

// DNSProvider specifies a DNS provider.
var DNSProvider string

// DNSProviderFlag selects a DNS provider.
var DNSProviderFlag = &cli.StringFlag{
	Name:        "provider, p",
	Value:       "",
	Usage:       "DNS provider",
	Destination: &DNSProvider,
}

var NoInput bool
var NoInputFlag = &cli.BoolFlag{
	Name:        "no-input, n",
	Usage:       "Toggle non-interactive mode",
	Destination: &NoInput,
}

var DNSType string

var DNSTypeFlag = &cli.StringFlag{
	Name:        "record-type, rt",
	Value:       "",
	Usage:       "Domain name record type (e.g. A)",
	Destination: &DNSType,
}

var DNSName string

var DNSNameFlag = &cli.StringFlag{
	Name:        "record-name, rn",
	Value:       "",
	Usage:       "Domain name record name (e.g. mysubdomain)",
	Destination: &DNSName,
}

var DNSValue string

var DNSValueFlag = &cli.StringFlag{
	Name:        "record-value, rv",
	Value:       "",
	Usage:       "Domain name record value (e.g. 192.168.1.1)",
	Destination: &DNSValue,
}

var DNSTTL string
var DNSTTLFlag = &cli.StringFlag{
	Name:        "record-ttl, rl",
	Value:       "600s",
	Usage:       "Domain name TTL value (seconds)",
	Destination: &DNSTTL,
}

var DNSPriority int

var DNSPriorityFlag = &cli.IntFlag{
	Name:        "record-priority, rp",
	Value:       10,
	Usage:       "Domain name priority value",
	Destination: &DNSPriority,
}

var ServerProvider string

var ServerProviderFlag = &cli.StringFlag{
	Name:        "provider, p",
	Usage:       "3rd party server provider",
	Destination: &ServerProvider,
}

var CapsulInstanceURL string

var CapsulInstanceURLFlag = &cli.StringFlag{
	Name:        "capsul-url, cu",
	Value:       "yolo.servers.coop",
	Usage:       "capsul instance URL",
	Destination: &CapsulInstanceURL,
}

var CapsulName string

var CapsulNameFlag = &cli.StringFlag{
	Name:        "capsul-name, cn",
	Value:       "",
	Usage:       "capsul name",
	Destination: &CapsulName,
}

var CapsulType string

var CapsulTypeFlag = &cli.StringFlag{
	Name:        "capsul-type, ct",
	Value:       "f1-xs",
	Usage:       "capsul type",
	Destination: &CapsulType,
}

var CapsulImage string

var CapsulImageFlag = &cli.StringFlag{
	Name:        "capsul-image, ci",
	Value:       "debian10",
	Usage:       "capsul image",
	Destination: &CapsulImage,
}

var CapsulSSHKeys cli.StringSlice
var CapsulSSHKeysFlag = &cli.StringSliceFlag{
	Name:  "capsul-ssh-keys, cs",
	Usage: "capsul SSH key",
	Value: &CapsulSSHKeys,
}

var CapsulAPIToken string

var CapsulAPITokenFlag = &cli.StringFlag{
	Name:        "capsul-token, ca",
	Usage:       "capsul API token",
	EnvVar:      "CAPSUL_TOKEN",
	Destination: &CapsulAPIToken,
}

var HetznerCloudName string

var HetznerCloudNameFlag = &cli.StringFlag{
	Name:        "hetzner-name, hn",
	Value:       "",
	Usage:       "hetzner cloud name",
	Destination: &HetznerCloudName,
}

var HetznerCloudType string

var HetznerCloudTypeFlag = &cli.StringFlag{
	Name:        "hetzner-type, ht",
	Usage:       "hetzner cloud type",
	Destination: &HetznerCloudType,
	Value:       "cx11",
}

var HetznerCloudImage string

var HetznerCloudImageFlag = &cli.StringFlag{
	Name:        "hetzner-image, hi",
	Usage:       "hetzner cloud image",
	Value:       "debian-10",
	Destination: &HetznerCloudImage,
}

var HetznerCloudSSHKeys cli.StringSlice

var HetznerCloudSSHKeysFlag = &cli.StringSliceFlag{
	Name:  "hetzner-ssh-keys, hs",
	Usage: "hetzner cloud SSH keys (e.g. me@foo.com)",
	Value: &HetznerCloudSSHKeys,
}

var HetznerCloudLocation string

var HetznerCloudLocationFlag = &cli.StringFlag{
	Name:        "hetzner-location, hl",
	Usage:       "hetzner cloud server location",
	Value:       "hel1",
	Destination: &HetznerCloudLocation,
}

var HetznerCloudAPIToken string

var HetznerCloudAPITokenFlag = &cli.StringFlag{
	Name:        "hetzner-token, ha",
	Usage:       "hetzner cloud API token",
	EnvVar:      "HCLOUD_TOKEN",
	Destination: &HetznerCloudAPIToken,
}

// Debug stores the variable from DebugFlag.
var Debug bool

// DebugFlag turns on/off verbose logging down to the DEBUG level.
var DebugFlag = &cli.BoolFlag{
	Name:        "debug, d",
	Destination: &Debug,
	Usage:       "Show DEBUG messages",
}

// MachineReadable stores the variable from MachineReadableFlag
var MachineReadable bool

// MachineReadableFlag turns on/off machine readable output where supported
var MachineReadableFlag = &cli.BoolFlag{
	Name:        "machine, m",
	Destination: &MachineReadable,
	Usage:       "Output in a machine-readable format (where supported)",
}

// RC signifies the latest release candidate
var RC bool

// RCFlag chooses the latest release candidate for install
var RCFlag = &cli.BoolFlag{
	Name:        "rc, r",
	Destination: &RC,
	Usage:       "Insatll the latest release candidate",
}

var Major bool
var MajorFlag = &cli.BoolFlag{
	Name:        "major, x",
	Usage:       "Increase the major part of the version",
	Destination: &Major,
}

var Minor bool
var MinorFlag = &cli.BoolFlag{
	Name:        "minor, y",
	Usage:       "Increase the minor part of the version",
	Destination: &Minor,
}

var Patch bool
var PatchFlag = &cli.BoolFlag{
	Name:        "patch, z",
	Usage:       "Increase the patch part of the version",
	Destination: &Patch,
}

var Dry bool
var DryFlag = &cli.BoolFlag{
	Name:        "dry-run, r",
	Usage:       "Only reports changes that would be made",
	Destination: &Dry,
}

var Publish bool
var PublishFlag = &cli.BoolFlag{
	Name:        "publish, p",
	Usage:       "Publish changes to git.coopcloud.tech",
	Destination: &Publish,
}

var Domain string
var DomainFlag = &cli.StringFlag{
	Name:        "domain, D",
	Value:       "",
	Usage:       "Choose a domain name",
	Destination: &Domain,
}

var NewAppServer string
var NewAppServerFlag = &cli.StringFlag{
	Name:        "server, s",
	Value:       "",
	Usage:       "Show apps of a specific server",
	Destination: &NewAppServer,
}

var NoDomainChecks bool
var NoDomainChecksFlag = &cli.BoolFlag{
	Name:        "no-domain-checks, D",
	Usage:       "Disable app domain sanity checks",
	Destination: &NoDomainChecks,
}

var StdErrOnly bool
var StdErrOnlyFlag = &cli.BoolFlag{
	Name:        "stderr, s",
	Usage:       "Only tail stderr",
	Destination: &StdErrOnly,
}

var SinceLogs string
var SinceLogsFlag = &cli.StringFlag{
	Name:        "since, S",
	Value:       "",
	Usage:       "tail logs since YYYY-MM-DDTHH:MM:SSZ",
	Destination: &SinceLogs,
}

var DontWaitConverge bool
var DontWaitConvergeFlag = &cli.BoolFlag{
	Name:        "no-converge-checks, c",
	Usage:       "Don't wait for converge logic checks",
	Destination: &DontWaitConverge,
}

var Watch bool
var WatchFlag = &cli.BoolFlag{
	Name:        "watch, w",
	Usage:       "Watch status by polling repeatedly",
	Destination: &Watch,
}

var OnlyErrors bool
var OnlyErrorFlag = &cli.BoolFlag{
	Name:        "errors, e",
	Usage:       "Only show errors",
	Destination: &OnlyErrors,
}

var SkipUpdates bool
var SkipUpdatesFlag = &cli.BoolFlag{
	Name:        "skip-updates, s",
	Usage:       "Skip updating recipe repositories",
	Destination: &SkipUpdates,
}

var AllTags bool
var AllTagsFlag = &cli.BoolFlag{
	Name:        "all-tags, a",
	Usage:       "List all tags, not just upgrades",
	Destination: &AllTags,
}

var LocalCmd bool
var LocalCmdFlag = &cli.BoolFlag{
	Name:        "local, l",
	Usage:       "Run command locally",
	Destination: &LocalCmd,
}

var RemoteUser string
var RemoteUserFlag = &cli.StringFlag{
	Name:        "user, u",
	Value:       "",
	Usage:       "User to run command within a service context",
	Destination: &RemoteUser,
}

// SubCommandBefore wires up pre-action machinery (e.g. --debug handling).
func SubCommandBefore(c *cli.Context) error {
	if Debug {
		logrus.SetLevel(logrus.DebugLevel)
		logrus.SetFormatter(&logrus.TextFormatter{})
		logrus.SetOutput(os.Stderr)
		logrus.AddHook(logrusStack.StandardHook())
	}

	return nil
}