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

package runtime

import (
	"unsafe"
)

const _DWORD_MAX = 0xffffffff

const _INVALID_HANDLE_VALUE = ^uintptr(0)

// net_op must be the same as beginning of internal/poll.operation.
// Keep these in sync.
type net_op struct {
	// used by windows
	o overlapped
	// used by netpoll
	pd    *pollDesc
	mode  int32
	errno int32
	qty   uint32
}

type overlappedEntry struct {
	key      uintptr
	op       *net_op // In reality it's *overlapped, but we cast it to *net_op anyway.
	internal uintptr
	qty      uint32
}

var iocphandle uintptr = _INVALID_HANDLE_VALUE // completion port io handle

func netpollinit() {
	iocphandle = stdcall4(_CreateIoCompletionPort, _INVALID_HANDLE_VALUE, 0, 0, _DWORD_MAX)
	if iocphandle == 0 {
		println("runtime: CreateIoCompletionPort failed (errno=", getlasterror(), ")")
		throw("runtime: netpollinit failed")
	}
}

func netpolldescriptor() uintptr {
	return iocphandle
}

func netpollopen(fd uintptr, pd *pollDesc) int32 {
	if stdcall4(_CreateIoCompletionPort, fd, iocphandle, 0, 0) == 0 {
		return -int32(getlasterror())
	}
	return 0
}

func netpollclose(fd uintptr) int32 {
	// nothing to do
	return 0
}

func netpollarm(pd *pollDesc, mode int) {
	throw("runtime: unused")
}

// Polls for completed network IO.
// Returns list of goroutines that become runnable.
func netpoll(block bool) *g {
	var entries [64]overlappedEntry
	var wait, qty, key, flags, n, i uint32
	var errno int32
	var op *net_op
	var gp guintptr

	mp := getg().m

	if iocphandle == _INVALID_HANDLE_VALUE {
		return nil
	}
	wait = 0
	if block {
		wait = _INFINITE
	}
retry:
	if _GetQueuedCompletionStatusEx != nil {
		n = uint32(len(entries) / int(gomaxprocs))
		if n < 8 {
			n = 8
		}
		if block {
			mp.blocked = true
		}
		if stdcall6(_GetQueuedCompletionStatusEx, iocphandle, uintptr(unsafe.Pointer(&entries[0])), uintptr(n), uintptr(unsafe.Pointer(&n)), uintptr(wait), 0) == 0 {
			mp.blocked = false
			errno = int32(getlasterror())
			if !block && errno == _WAIT_TIMEOUT {
				return nil
			}
			println("runtime: GetQueuedCompletionStatusEx failed (errno=", errno, ")")
			throw("runtime: netpoll failed")
		}
		mp.blocked = false
		for i = 0; i < n; i++ {
			op = entries[i].op
			errno = 0
			qty = 0
			if stdcall5(_WSAGetOverlappedResult, op.pd.fd, uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 {
				errno = int32(getlasterror())
			}
			handlecompletion(&gp, op, errno, qty)
		}
	} else {
		op = nil
		errno = 0
		qty = 0
		if block {
			mp.blocked = true
		}
		if stdcall5(_GetQueuedCompletionStatus, iocphandle, uintptr(unsafe.Pointer(&qty)), uintptr(unsafe.Pointer(&key)), uintptr(unsafe.Pointer(&op)), uintptr(wait)) == 0 {
			mp.blocked = false
			errno = int32(getlasterror())
			if !block && errno == _WAIT_TIMEOUT {
				return nil
			}
			if op == nil {
				println("runtime: GetQueuedCompletionStatus failed (errno=", errno, ")")
				throw("runtime: netpoll failed")
			}
			// dequeued failed IO packet, so report that
		}
		mp.blocked = false
		handlecompletion(&gp, op, errno, qty)
	}
	if block && gp == 0 {
		goto retry
	}
	return gp.ptr()
}

func handlecompletion(gpp *guintptr, op *net_op, errno int32, qty uint32) {
	if op == nil {
		println("runtime: GetQueuedCompletionStatus returned op == nil")
		throw("runtime: netpoll failed")
	}
	mode := op.mode
	if mode != 'r' && mode != 'w' {
		println("runtime: GetQueuedCompletionStatus returned invalid mode=", mode)
		throw("runtime: netpoll failed")
	}
	op.errno = errno
	op.qty = qty
	netpollready(gpp, op.pd, mode)
}
