package mounttable

import (
	"container/list"
	"sync"
	"time"

	"v.io/core/veyron2/naming"
	"v.io/core/veyron2/security"
)

type serverListClock interface {
	now() time.Time
}

type realTime bool

func (t realTime) now() time.Time {
	return time.Now()
}

// TODO(caprita): Replace this with the timekeeper library.
var slc = serverListClock(realTime(true))

// server maintains the state of a single server.  Unless expires is refreshed before the
// time is reached, the entry will be removed.
type server struct {
	expires  time.Time
	oa       string   // object address of server
	patterns []string // patterns that server blessings should match
}

// serverList represents an ordered list of servers.
type serverList struct {
	sync.Mutex
	l *list.List // contains entries of type *server
}

// newServerList creates a synchronized list of servers.
func newServerList() *serverList {
	return &serverList{l: list.New()}
}

// set up an alternate clock.
func setServerListClock(x serverListClock) {
	slc = x
}

func (sl *serverList) len() int {
	sl.Lock()
	defer sl.Unlock()
	return sl.l.Len()
}

func (sl *serverList) Front() *server {
	sl.Lock()
	defer sl.Unlock()
	return sl.l.Front().Value.(*server)
}

// add to the front of the list if not already in the list, otherwise,
// update the expiration time and move to the front of the list.  That
// way the most recently refreshed is always first.
func (sl *serverList) add(oa string, patterns []security.BlessingPattern, ttl time.Duration) {
	expires := slc.now().Add(ttl)
	strpats := make([]string, len(patterns))
	for idx, pat := range patterns {
		strpats[idx] = string(pat)
	}
	sl.Lock()
	defer sl.Unlock()
	for e := sl.l.Front(); e != nil; e = e.Next() {
		s := e.Value.(*server)
		if s.oa == oa {
			s.expires = expires
			sl.l.MoveToFront(e)
			return
		}
	}
	s := &server{
		oa:       oa,
		expires:  expires,
		patterns: strpats,
	}
	sl.l.PushFront(s) // innocent until proven guilty
}

// remove an element from the list.  Return the number of elements remaining.
func (sl *serverList) remove(oa string) int {
	sl.Lock()
	defer sl.Unlock()
	for e := sl.l.Front(); e != nil; e = e.Next() {
		s := e.Value.(*server)
		if s.oa == oa {
			sl.l.Remove(e)
			break
		}
	}
	return sl.l.Len()
}

// removeExpired removes any expired servers.
func (sl *serverList) removeExpired() int {
	sl.Lock()
	defer sl.Unlock()

	now := slc.now()
	var next *list.Element
	for e := sl.l.Front(); e != nil; e = next {
		s := e.Value.(*server)
		next = e.Next()
		if now.After(s.expires) {
			sl.l.Remove(e)
		}
	}
	return sl.l.Len()
}

// copyToSlice returns the contents of the list as a slice of MountedServer.
func (sl *serverList) copyToSlice() []naming.VDLMountedServer {
	sl.Lock()
	defer sl.Unlock()
	var slice []naming.VDLMountedServer
	now := slc.now()
	for e := sl.l.Front(); e != nil; e = e.Next() {
		s := e.Value.(*server)
		ttl := uint32(s.expires.Sub(now).Seconds())
		ms := naming.VDLMountedServer{Server: s.oa, BlessingPatterns: s.patterns, TTL: ttl}
		slice = append(slice, ms)
	}
	return slice
}
