// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Waiting for FDs via kqueue/kevent.

package net

import (
	"errors"
	"os"
	"syscall"
)

type pollster struct {
	kq       int
	eventbuf [10]syscall.Kevent_t
	events   []syscall.Kevent_t

	// An event buffer for AddFD/DelFD.
	// Must hold pollServer lock.
	kbuf [1]syscall.Kevent_t
}

func newpollster() (p *pollster, err error) {
	p = new(pollster)
	if p.kq, err = syscall.Kqueue(); err != nil {
		return nil, os.NewSyscallError("kqueue", err)
	}
	syscall.CloseOnExec(p.kq)
	p.events = p.eventbuf[0:0]
	return p, nil
}

func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) {
	// pollServer is locked.

	var kmode int
	if mode == 'r' {
		kmode = syscall.EVFILT_READ
	} else {
		kmode = syscall.EVFILT_WRITE
	}
	ev := &p.kbuf[0]
	// EV_ADD - add event to kqueue list
	// EV_RECEIPT - generate fake EV_ERROR as result of add,
	//	rather than waiting for real event
	// EV_ONESHOT - delete the event the first time it triggers
	flags := syscall.EV_ADD | syscall.EV_RECEIPT
	if !repeat {
		flags |= syscall.EV_ONESHOT
	}
	syscall.SetKevent(ev, fd, kmode, flags)

	n, err := syscall.Kevent(p.kq, p.kbuf[0:], p.kbuf[0:], nil)
	if err != nil {
		return false, os.NewSyscallError("kevent", err)
	}
	if n != 1 || (ev.Flags&syscall.EV_ERROR) == 0 || int(ev.Ident) != fd || int(ev.Filter) != kmode {
		return false, errors.New("kqueue phase error")
	}
	if ev.Data != 0 {
		return false, syscall.Errno(ev.Data)
	}
	return false, nil
}

func (p *pollster) DelFD(fd int, mode int) {
	// pollServer is locked.

	var kmode int
	if mode == 'r' {
		kmode = syscall.EVFILT_READ
	} else {
		kmode = syscall.EVFILT_WRITE
	}
	ev := &p.kbuf[0]
	// EV_DELETE - delete event from kqueue list
	// EV_RECEIPT - generate fake EV_ERROR as result of add,
	//	rather than waiting for real event
	syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE|syscall.EV_RECEIPT)
	syscall.Kevent(p.kq, p.kbuf[0:], p.kbuf[0:], nil)
}

func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) {
	var t *syscall.Timespec
	for len(p.events) == 0 {
		if nsec > 0 {
			if t == nil {
				t = new(syscall.Timespec)
			}
			*t = syscall.NsecToTimespec(nsec)
		}

		s.Unlock()
		nn, e := syscall.Kevent(p.kq, nil, p.eventbuf[0:], t)
		s.Lock()

		if e != nil {
			if e == syscall.EINTR {
				continue
			}
			return -1, 0, os.NewSyscallError("kevent", nil)
		}
		if nn == 0 {
			return -1, 0, nil
		}
		p.events = p.eventbuf[0:nn]
	}
	ev := &p.events[0]
	p.events = p.events[1:]
	fd = int(ev.Ident)
	if ev.Filter == syscall.EVFILT_READ {
		mode = 'r'
	} else {
		mode = 'w'
	}
	return fd, mode, nil
}

func (p *pollster) Close() error { return os.NewSyscallError("close", syscall.Close(p.kq)) }
