package cluster

import (
	"io/fs"
)

var (
	_ MachineIterator = (*Zone)(nil)
)

// A ZoneIterator is a set of Zones we can iterate on
type ZoneIterator interface {
	ForEachZone(func(*Zone) bool)
}

// A Zone is a set of machines in close proximity and strong
// affinity.
type Zone struct {
	zones  *Cluster
	logger `json:"-" yaml:"-"`

	ID      int
	Name    string
	Regions []string `json:",omitempty" yaml:",omitempty"`

	Machines
}

func (z *Zone) String() string {
	return z.Name
}

// SetGateway configures a machine to be the zone's ring0 gateway
func (z *Zone) SetGateway(gatewayID int, enabled bool) error {
	var err error
	var found bool

	z.ForEachMachine(func(p *Machine) bool {
		if p.ID == gatewayID {
			found = true
			err = p.SetGateway(enabled)

			return true
		}
		return false
	})

	switch {
	case err != nil:
		return err
	case !found:
		return fs.ErrNotExist
	default:
		return nil
	}
}

// GatewayIDs returns the list of IDs of machines that act as ring0 gateways
func (z *Zone) GatewayIDs() ([]int, int) {
	var out []int
	z.ForEachMachine(func(p *Machine) bool {
		if p.IsGateway() {
			out = append(out, p.ID)
		}
		return false
	})

	return out, len(out)
}