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

// +build darwin dragonfly freebsd linux netbsd openbsd

package poll

import (
	"io"
	"syscall"
)

// Writev wraps the writev system call.
func (fd *FD) Writev(v *[][]byte) (int64, error) {
	if err := fd.writeLock(); err != nil {
		return 0, err
	}
	defer fd.writeUnlock()
	if err := fd.pd.prepareWrite(fd.isFile); err != nil {
		return 0, err
	}

	var iovecs []syscall.Iovec
	if fd.iovecs != nil {
		iovecs = *fd.iovecs
	}
	// TODO: read from sysconf(_SC_IOV_MAX)? The Linux default is
	// 1024 and this seems conservative enough for now. Darwin's
	// UIO_MAXIOV also seems to be 1024.
	maxVec := 1024

	var n int64
	var err error
	for len(*v) > 0 {
		iovecs = iovecs[:0]
		for _, chunk := range *v {
			if len(chunk) == 0 {
				continue
			}
			iovecs = append(iovecs, syscall.Iovec{Base: &chunk[0]})
			if fd.IsStream && len(chunk) > 1<<30 {
				iovecs[len(iovecs)-1].SetLen(1 << 30)
				break // continue chunk on next writev
			}
			iovecs[len(iovecs)-1].SetLen(len(chunk))
			if len(iovecs) == maxVec {
				break
			}
		}
		if len(iovecs) == 0 {
			break
		}
		fd.iovecs = &iovecs // cache

		var wrote uintptr
		wrote, err = writev(fd.Sysfd, iovecs)
		if wrote == ^uintptr(0) {
			wrote = 0
		}
		TestHookDidWritev(int(wrote))
		n += int64(wrote)
		consume(v, int64(wrote))
		if err != nil {
			if err.(syscall.Errno) == syscall.EAGAIN {
				if err = fd.pd.waitWrite(fd.isFile); err == nil {
					continue
				}
			}
			break
		}
		if n == 0 {
			err = io.ErrUnexpectedEOF
			break
		}
	}
	return n, err
}
