// Copyright 2020 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.

//go:build zos && s390x
// +build zos,s390x

package unix

import (
	"sync"
)

// This file simulates epoll on z/OS using poll.

// Analogous to epoll_event on Linux.
// TODO(neeilan): Pad is because the Linux kernel expects a 96-bit struct. We never pass this to the kernel; remove?
type EpollEvent struct {
	Events uint32
	Fd     int32
	Pad    int32
}

const (
	EPOLLERR      = 0x8
	EPOLLHUP      = 0x10
	EPOLLIN       = 0x1
	EPOLLMSG      = 0x400
	EPOLLOUT      = 0x4
	EPOLLPRI      = 0x2
	EPOLLRDBAND   = 0x80
	EPOLLRDNORM   = 0x40
	EPOLLWRBAND   = 0x200
	EPOLLWRNORM   = 0x100
	EPOLL_CTL_ADD = 0x1
	EPOLL_CTL_DEL = 0x2
	EPOLL_CTL_MOD = 0x3
	// The following constants are part of the epoll API, but represent
	// currently unsupported functionality on z/OS.
	// EPOLL_CLOEXEC  = 0x80000
	// EPOLLET        = 0x80000000
	// EPOLLONESHOT   = 0x40000000
	// EPOLLRDHUP     = 0x2000     // Typically used with edge-triggered notis
	// EPOLLEXCLUSIVE = 0x10000000 // Exclusive wake-up mode
	// EPOLLWAKEUP    = 0x20000000 // Relies on Linux's BLOCK_SUSPEND capability
)

// TODO(neeilan): We can eliminate these epToPoll / pToEpoll calls by using identical mask values for POLL/EPOLL
// constants where possible The lower 16 bits of epoll events (uint32) can fit any system poll event (int16).

// epToPollEvt converts epoll event field to poll equivalent.
// In epoll, Events is a 32-bit field, while poll uses 16 bits.
func epToPollEvt(events uint32) int16 {
	var ep2p = map[uint32]int16{
		EPOLLIN:  POLLIN,
		EPOLLOUT: POLLOUT,
		EPOLLHUP: POLLHUP,
		EPOLLPRI: POLLPRI,
		EPOLLERR: POLLERR,
	}

	var pollEvts int16 = 0
	for epEvt, pEvt := range ep2p {
		if (events & epEvt) != 0 {
			pollEvts |= pEvt
		}
	}

	return pollEvts
}

// pToEpollEvt converts 16 bit poll event bitfields to 32-bit epoll event fields.
func pToEpollEvt(revents int16) uint32 {
	var p2ep = map[int16]uint32{
		POLLIN:  EPOLLIN,
		POLLOUT: EPOLLOUT,
		POLLHUP: EPOLLHUP,
		POLLPRI: EPOLLPRI,
		POLLERR: EPOLLERR,
	}

	var epollEvts uint32 = 0
	for pEvt, epEvt := range p2ep {
		if (revents & pEvt) != 0 {
			epollEvts |= epEvt
		}
	}

	return epollEvts
}

// Per-process epoll implementation.
type epollImpl struct {
	mu       sync.Mutex
	epfd2ep  map[int]*eventPoll
	nextEpfd int
}

// eventPoll holds a set of file descriptors being watched by the process. A process can have multiple epoll instances.
// On Linux, this is an in-kernel data structure accessed through a fd.
type eventPoll struct {
	mu  sync.Mutex
	fds map[int]*EpollEvent
}

// epoll impl for this process.
var impl epollImpl = epollImpl{
	epfd2ep:  make(map[int]*eventPoll),
	nextEpfd: 0,
}

func (e *epollImpl) epollcreate(size int) (epfd int, err error) {
	e.mu.Lock()
	defer e.mu.Unlock()
	epfd = e.nextEpfd
	e.nextEpfd++

	e.epfd2ep[epfd] = &eventPoll{
		fds: make(map[int]*EpollEvent),
	}
	return epfd, nil
}

func (e *epollImpl) epollcreate1(flag int) (fd int, err error) {
	return e.epollcreate(4)
}

func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) {
	e.mu.Lock()
	defer e.mu.Unlock()

	ep, ok := e.epfd2ep[epfd]
	if !ok {

		return EBADF
	}

	switch op {
	case EPOLL_CTL_ADD:
		// TODO(neeilan): When we make epfds and fds disjoint, detect epoll
		// loops here (instances watching each other) and return ELOOP.
		if _, ok := ep.fds[fd]; ok {
			return EEXIST
		}
		ep.fds[fd] = event
	case EPOLL_CTL_MOD:
		if _, ok := ep.fds[fd]; !ok {
			return ENOENT
		}
		ep.fds[fd] = event
	case EPOLL_CTL_DEL:
		if _, ok := ep.fds[fd]; !ok {
			return ENOENT
		}
		delete(ep.fds, fd)

	}
	return nil
}

// Must be called while holding ep.mu
func (ep *eventPoll) getFds() []int {
	fds := make([]int, len(ep.fds))
	for fd := range ep.fds {
		fds = append(fds, fd)
	}
	return fds
}

func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) {
	e.mu.Lock() // in [rare] case of concurrent epollcreate + epollwait
	ep, ok := e.epfd2ep[epfd]

	if !ok {
		e.mu.Unlock()
		return 0, EBADF
	}

	pollfds := make([]PollFd, 4)
	for fd, epollevt := range ep.fds {
		pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)})
	}
	e.mu.Unlock()

	n, err = Poll(pollfds, msec)
	if err != nil {
		return n, err
	}

	i := 0
	for _, pFd := range pollfds {
		if pFd.Revents != 0 {
			events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)}
			i++
		}

		if i == n {
			break
		}
	}

	return n, nil
}

func EpollCreate(size int) (fd int, err error) {
	return impl.epollcreate(size)
}

func EpollCreate1(flag int) (fd int, err error) {
	return impl.epollcreate1(flag)
}

func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
	return impl.epollctl(epfd, op, fd, event)
}

// Because EpollWait mutates events, the caller is expected to coordinate
// concurrent access if calling with the same epfd from multiple goroutines.
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
	return impl.epollwait(epfd, events, msec)
}
