package suite

import (
	"os"
	"path"
	"time"

	"github.com/spf13/pflag"
)

type AWSOptions struct {
	ReuseNetwork string
	Region       string
	// TODO: combine profile and account
	Profile string
	Account string

	OldProvider InfraProviderOptions
	NewProvider InfraProviderOptions
}

type GCPOptions struct {
	ReuseNetwork string
	Region       string

	OldProvider InfraProviderOptions
	NewProvider InfraProviderOptions
}

const (
	RuntimeTypeLocal  = "local"
	RuntimeTypeDocker = "docker"
)

type Runtime struct {
	Type      string
	Image     string
	ExtraArgs []string
}

type InfraProviderOptions struct {
	Runtime Runtime
	Cmd     string
	Config  string
	LogFile string
}

type Options struct {
	Seed            int64
	InfraAPIConfig  string
	InfraAPIContext string

	BaseConfig  string
	BaseContext string

	Selector string
	Project  string
	Account  string
	AWS      AWSOptions
	GCP      GCPOptions
}

func (opt *Options) RegisterFlags(fs *pflag.FlagSet) {
	fs.Int64Var(&opt.Seed, "seed", opt.Seed, "random seed to generate all random string")
	fs.StringVar(&opt.InfraAPIConfig,
		"infra-api-config",
		opt.InfraAPIConfig,
		"config of infra api cluster")
	fs.StringVar(&opt.InfraAPIContext,
		"infra-api-context",
		opt.InfraAPIContext,
		"context of infra api cluster")

	fs.StringVar(&opt.BaseConfig,
		"base-config",
		opt.BaseConfig,
		"config of base cluster")
	fs.StringVar(&opt.BaseContext,
		"base-context",
		opt.BaseContext,
		"context of base cluster")

	fs.StringVar(&opt.Selector,
		"selector",
		opt.Selector,
		"selector for cases",
	)

	fs.StringVar(&opt.Project, "project", opt.Project, "project for cases")

	fs.StringVar(&opt.AWS.Region,
		"aws.region",
		opt.AWS.Region,
		"aws region of network",
	)
	fs.StringVar(&opt.AWS.ReuseNetwork,
		"aws.reuse-network",
		opt.AWS.ReuseNetwork,
		"eks network which will be reused for test",
	)
	fs.StringVar(&opt.AWS.Profile,
		"aws.profile",
		opt.AWS.Profile,
		"aws profile for aws api call",
	)
	fs.StringVar(&opt.AWS.Account, "aws.account", opt.AWS.Account, "name of cloudv1.Account to run tests in aws")

	fs.StringVar(&opt.GCP.Region,
		"gcp.region",
		opt.GCP.Region,
		"gcp region of network",
	)

	registerInfraProviderFlags(fs, "aws.old-provider", &opt.AWS.OldProvider)
	registerInfraProviderFlags(fs, "aws.new-provider", &opt.AWS.NewProvider)
	registerInfraProviderFlags(fs, "gcp.old-provider", &opt.GCP.OldProvider)
	registerInfraProviderFlags(fs, "gcp.new-provider", &opt.GCP.NewProvider)
}

func registerInfraProviderFlags(fs *pflag.FlagSet, prefix string, p *InfraProviderOptions) {
	fs.StringVar(&p.Runtime.Type, prefix+".runtime-type", p.Runtime.Type, "runtime type")
	fs.StringVar(&p.Runtime.Image, prefix+".runtime-image", p.Runtime.Image, "runtime image")
	fs.StringSliceVar(&p.Runtime.ExtraArgs, prefix+".runtime-extra-args", p.Runtime.ExtraArgs, "extra args")
	fs.StringVar(&p.Cmd, prefix+".cmd", p.Cmd, "cmd path")
	fs.StringVar(&p.Config, prefix+".config", p.Config, "config path")
	fs.StringVar(&p.LogFile, prefix+".log-file", p.LogFile, "log file path")

}

func NewOptions() *Options {
	return &Options{
		Seed:           time.Now().UnixNano(),
		InfraAPIConfig: path.Join(os.Getenv("HOME"), ".kube", "config"),
		BaseConfig:     path.Join(os.Getenv("HOME"), ".kube", "config"),
		Project:        "test",
		Account:        "",
		AWS: AWSOptions{
			Region:  os.Getenv("AWS_REGION"),
			Account: "aws-200683210682",
			OldProvider: InfraProviderOptions{
				Runtime: Runtime{
					Type: RuntimeTypeLocal,
				},
			},
			NewProvider: InfraProviderOptions{
				Runtime: Runtime{
					Type: RuntimeTypeLocal,
				},
			},
		},
		GCP: GCPOptions{
			Region: os.Getenv("GCP_REGION"),
			OldProvider: InfraProviderOptions{
				Runtime: Runtime{
					Type: RuntimeTypeLocal,
				},
			},
			NewProvider: InfraProviderOptions{
				Runtime: Runtime{
					Type: RuntimeTypeLocal,
				},
			},
		},
	}
}
