package ghpkg

import (
	"io/ioutil"
	"strings"

	"github.com/pingcap/test-infra/common/model"
)

// Config is the spec of plans, it should located on the root dir of each branch
type Config struct {
	// RecycleBin set no-index directory or path
	RecycleBin []PlanPathOrName `json:"recycle_bin" yaml:"recycle_bin"`
	// Whitelist takes effective only on feature branch, it's ignore on release branch
	// and on release branch Blacklist come on stage.
	Whitelist []PlanPathOrName `json:"whitelist,omitempty" yaml:"whitelist,omitempty"`
	// Blacklist takes effective only on release branch, it's ignore on feature branch
	// and on feature branch Whitelist come on stage.
	Blacklist []PlanPathOrName `json:"blacklist,omitempty" yaml:"blacklist,omitempty"`
	// ReleaseList defines the whitelist of plans on release
	ReleaseList []PlanPathOrName `json:"release,omitempty" yaml:"release,omitempty"`
	// disableSchedule on main/release- branch
	DisableSchedule bool `json:"disable_schedule,omitempty" yaml:"disable_schedule,omitempty"`
	// Priorities used to set the schedule priority of plan execution
	Priorities map[int][]string `json:"priorities,omitempty" yaml:"priorities,omitempty"`

	ResourcePool []ResourcePoolItem `json:"resourcePool,omitempty" yaml:"resourcePool,omitempty"`
	// Parameters can be used to substitute variables `{{meta.parameters.$parameter}}` part on each github plan template
	Parameters map[string]string `json:"parameters,omitempty" yaml:"parameters,omitempty"`
	// SyncToECRImages manually registers the images that should sync to ECR
	SyncToECRImages []string `json:"syncToECRImages" yaml:"syncToECRImages"`
}

func (c *Config) Init() error {
	// support parameters refer other parameters, we only support one jump substitute
	for key, value := range c.Parameters {
		reader, err := SubstituteVars(value, c.Parameters)
		if err != nil {
			return err
		}
		body, err := ioutil.ReadAll(reader)
		if err != nil {
			return err
		}
		c.Parameters[key] = string(body)
	}
	return nil
}

type PlanPathOrNameType string

const (
	PlanPathOrNameDirType  PlanPathOrNameType = "PLAN_DIR"
	PlanPathOrNameFileType PlanPathOrNameType = "PLAN_FILE"
	PlanPathOrNameNameType PlanPathOrNameType = "PLAN_NAME"
)

type PlanPathOrName string

func (p PlanPathOrName) Type() PlanPathOrNameType {
	switch {
	case model.PlanNameValidationRule.Validate(p) == nil:
		return PlanPathOrNameNameType
	case strings.HasSuffix(string(p), ".yaml"), strings.HasSuffix(string(p), ".yml"), strings.HasSuffix(string(p), tplJsonnetExt):
		return PlanPathOrNameFileType
	default:
		return PlanPathOrNameDirType
	}
}
