package ether

import (
	"sync"

	"github.com/juju/errors"
	"github.com/ngaut/log"
)

const (
	contractLease = 120
)

// Cluster is used for for resources management.
type Cluster struct {
	sync.RWMutex

	s       *Server
	running bool

	// cache cluster info.
	cached *clusterInfo
	// handle schedulers.
	controller *controller

	wg sync.WaitGroup
}

func newCluster(s *Server) *Cluster {
	return &Cluster{
		s: s,
	}
}

func (c *Cluster) start() error {
	c.Lock()
	defer c.Unlock()

	if c.running {
		log.Warn("[ether] cluster has already been started")
		return nil
	}

	cluster, err := loadClusterInfo(c.s.clusterID, c.s.kv, c.s.idAlloc)
	if err != nil {
		return errors.Trace(err)
	}
	c.cached = cluster

	c.controller = newController(c.cached, c.s.hbStreams, c.s.GetClient(), c.s.getClusterRootPath())
	go c.runController()

	c.running = true
	return nil
}

func (c *Cluster) runController() {
	c.wg.Add(1)
	c.controller.run()
	c.wg.Done()
}

func (c *Cluster) stop() {
	c.Lock()
	defer c.Unlock()

	if !c.running {
		return
	}
	c.running = false

	if c.controller != nil {
		c.controller.stop()
	}
	c.wg.Wait()
}

func (c *Cluster) isRunning() bool {
	c.RLock()
	defer c.RUnlock()

	return c.running
}
