package entity

type ApproverFromParam struct {
	ParamName         string               `json:"param_name" yaml:"paramName"`                            // The name of param
	ParamValueMapping map[string]*Approver `json:"param_value_mapping" yaml:"paramValueMapping,omitempty"` // The value of param to approver
	UseParamValue     bool                 `json:"use_param_value" yaml:"useParamValue,omitempty"`         // Use the param value as the approver email directly
	DefaultApprover   *Approver            `json:"default_approver" yaml:"defaultApprover,omitempty"`      // The default approver used when approver not found
}

type Approver struct {
	Email           string             `json:"email,omitempty" yaml:"email,omitempty"`                      // Email of approver
	Emails          []string           `json:"emails,omitempty" yaml:"emails,omitempty"`                    // Emails of approvers
	UserGroup       string             `json:"user_group,omitempty" yaml:"userGroup,omitempty"`             // User group of approvers, defined in user service
	UserGroups      []string           `json:"user_groups,omitempty" yaml:"userGroups,omitempty"`           // User groups of approvers, defined in user service
	ApplicantLeader bool               `json:"applicant_leader,omitempty" yaml:"applicantLeader,omitempty"` // The applicant leader is approver
	SelfApprove     bool               `json:"self_approve,omitempty" yaml:"selfApprove,omitempty"`         // The applicant can approve the request by himself
	FromParam       *ApproverFromParam `json:"from_param,omitempty" yaml:"fromParam,omitempty"`             // The approver is generated from param
}

type ApproverNode struct {
	*Approver `json:",inline" yaml:",inline"`

	// Name is the name of this node.
	Name string `json:"name" yaml:"name,omitempty"`
	// Method is the approval method, contains ANY, ALL.
	Method ApproveMethod `json:"method" yaml:"method"`
	// Skip this node when the approver is empty
	SkipWhenEmpty bool `json:"skip_when_empty,omitempty" yaml:"skipWhenEmpty,omitempty"`
	// Condition is a string expression that evaluates to true or false. If false,
	// this node will be skipped.
	//
	// Refer to https://github.com/expr-lang/expr
	Condition string `json:"condition,omitempty" yaml:"condition,omitempty"`
	// Parallel defines the parallel approver nodes.
	//
	// If it is set, the other fields are ignored.
	//
	// Only one level of parallel nodes is supported.
	Parallel []*ApproverNode `json:"parallel,omitempty" yaml:"parallel,omitempty"`
}

func (n *ApproverNode) EffectiveApproverNodes() []*ApproverNode {
	if len(n.Parallel) > 0 {
		return n.Parallel
	}
	return []*ApproverNode{n}
}

type Template struct {
	// ID is the template identifier
	ID string `json:"id,omitempty" yaml:"id,omitempty"`
	// Nodes is the approval nodes.
	//
	// If it is empty, the approval will be approved after created.
	Nodes []*ApproverNode `json:"nodes" yaml:"nodes"`
	// CCTasks defines the users who will be notified when the approval request is **Approved**.
	CCTasks *Approver `json:"cc_tasks,omitempty" yaml:"ccTasks,omitempty"`
	// AdminTasks is the users who can approve/reject/cancel the approval request at any time.
	AdminTasks *Approver `json:"admin_tasks,omitempty" yaml:"adminTasks,omitempty"`
}
