package config

import "github.com/elliotchance/pie/v2"

// FeatureGate defines the feature gate config structure.
// - Provider: aws, gcp, azure, etc.
//
// - Region: "us-west-1", "asia-southeast1", "eastus2", etc. (plain cloud region without provider prefix)
//
//	Priority order:
//
// - RequiredXXX take priority over DisabledXXX
//
// - DisabledXXX take priority over EnabledXXX
//
// - EnabledXXX take priority over All
//
// - All is fallback enable flag
type FeatureGate struct {
	RequiredProviders []string `mapstructure:"requiredProviders"`
	RequiredRegions   []string `mapstructure:"requiredRegions"`

	DisabledProviders []string `mapstructure:"disabledProviders"`
	DisabledRegions   []string `mapstructure:"disabledRegions"`
	DisabledTenants   []uint64 `mapstructure:"disabledTenants"`
	DisabledProjects  []uint64 `mapstructure:"disabledProjects"`
	DisabledClusters  []uint64 `mapstructure:"disabledClusters"`

	EnabledProviders []string `mapstructure:"enabledProviders"`
	EnabledRegions   []string `mapstructure:"enabledRegions"`
	EnabledTenants   []uint64 `mapstructure:"enabledTenants"`
	EnabledProjects  []uint64 `mapstructure:"enabledProjects"`
	EnabledClusters  []uint64 `mapstructure:"enabledClusters"`

	All bool `mapstructure:"all" default:"false"`
}

// FeatureGateQueryParams is the parameters for querying feature gate.
// empty parameter means not specified, should be ignored.
type FeatureGateQueryParams struct {
	Provider  string // aws, gcp, azure, etc.
	Region    string // "us-west-1", "asia-southeast1", "eastus2", etc.
	TenantID  uint64
	ProjectID uint64
	ClusterID uint64
}

func (g *FeatureGate) Enabled(params FeatureGateQueryParams) (reason string, _ bool) {
	// Priority: Required > Disabled > Enabled > All

	// 1. Check Required conditions (if any matches, return true immediately)
	if params.Provider != "" && pie.Contains(g.RequiredProviders, params.Provider) {
		return "required-provider", true
	}
	if params.Region != "" && pie.Contains(g.RequiredRegions, params.Region) {
		return "required-region", true
	}

	// 2. Check Disabled conditions (if any matches, return false immediately)
	// DisabledProviders
	if params.Provider != "" && pie.Contains(g.DisabledProviders, params.Provider) {
		return "disabled-provider", false
	}
	if params.Region != "" && pie.Contains(g.DisabledRegions, params.Region) {
		return "disabled-region", false
	}
	if params.TenantID != 0 && pie.Contains(g.DisabledTenants, params.TenantID) {
		return "disabled-tenant", false
	}
	if params.ProjectID != 0 && pie.Contains(g.DisabledProjects, params.ProjectID) {
		return "disabled-project", false
	}
	if params.ClusterID != 0 && pie.Contains(g.DisabledClusters, params.ClusterID) {
		return "disabled-cluster", false
	}

	// 3. Check Enabled conditions (if any matches, return true)
	if params.Provider != "" && pie.Contains(g.EnabledProviders, params.Provider) {
		return "enabled-provider", true
	}
	if params.Region != "" && pie.Contains(g.EnabledRegions, params.Region) {
		return "enabled-region", true
	}
	if params.TenantID != 0 && pie.Contains(g.EnabledTenants, params.TenantID) {
		return "enabled-tenant", true
	}
	if params.ProjectID != 0 && pie.Contains(g.EnabledProjects, params.ProjectID) {
		return "enabled-project", true
	}
	if params.ClusterID != 0 && pie.Contains(g.EnabledClusters, params.ClusterID) {
		return "enabled-cluster", true
	}

	// 4. Fallback to All flag
	return "fallback-all", g.All
}
