package impl

import (
	"sort"
	"strings"

	"github.com/elliotchance/pie/v2"
	"github.com/tidbcloud/dataflow-service/app/internal/feature_gate"
	"github.com/tidbcloud/dataflow-service/internal/config"
)

type featureGate struct{}

func NewFeatureGate() feature_gate.FeatureGate {
	return &featureGate{}
}

func (f *featureGate) QueryEnabledFeatures(req *feature_gate.QueryFeatureGateReq) feature_gate.QueryFeatureGateResp {
	flags := map[string]bool{}
	var features []string
	addFeature := func(feature string, fs ...func() bool) {
		feature = strings.ToLower(feature)
		_, ok := flags[feature]
		if ok {
			return
		}
		for _, f := range fs {
			if !f() {
				return
			}
		}
		flags[feature] = true
		features = append(features, feature)
	}

	switchers := config.Global().ServerConfig.FeaturesSwitchers
	// public features
	for _, feature := range switchers.PublicFeatures {
		addFeature(feature)
	}
	// feature enabled by how it's deployed
	for feature, matcher := range switchers.EnabledFeatureByDeployment {
		addFeature(feature, func() bool {
			return matcher.Match(req.Region, req.InfraProvider)
		})
	}
	// allow list features
	for feature, matcher := range switchers.FeaturesAllowList {
		addFeature(feature, func() bool {
			return matcher.Match(req.TenantID, req.ProjectID, req.ClusterID, req.Region, req.InfraProvider)
		})
	}
	sort.Strings(features)
	return feature_gate.QueryFeatureGateResp{Features: features}
}

func (f *featureGate) IsFeatureEnabled(req *feature_gate.QueryFeatureGateReq, feature string) bool {
	features := f.QueryEnabledFeatures(req)
	if len(features.Features) == 0 {
		return false
	}
	return pie.Of(features.Features).Any(func(s string) bool {
		return s == feature
	})
}
