// Copyright 2018 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 fuchsia

package fdio

import (
	"syscall/zx"
	"syscall/zx/io"
)

// File is a wrapper around a FileInterface which implements FDIO.
type File struct {
	Node
	Event zx.Event
}

// FileInterface returns the underlying File FIDL interface.
func (f *File) FileInterface() *io.FileInterface {
	return (*io.FileInterface)(f.Node.Object.ObjectInterface)
}

// Handles returns all the underlying handles for this file,
// which is the control channel and an event.
func (f *File) Handles() []zx.Handle {
	return append(f.Node.Handles(), zx.Handle(f.Event))
}

// Close closes all the control channel and event associated with the file
// object.
func (f *File) Close() error {
	defer f.Event.Close()
	return f.Node.Close()
}

// read reads data from a File. If off == -1 then it does a read
// from whatever the seek offset is.
func (f *File) read(data []byte, off int64) (int, error) {
	ptr := 0
	for ptr < len(data) {
		bytesToRead := int(io.KMaxBuf)
		if len(data)-ptr < int(io.KMaxBuf) {
			bytesToRead = len(data) - ptr
		}
		var status zx.Status
		var out []byte
		var err error
		if off == -1 {
			status, out, err = f.FileInterface().Read(uint64(bytesToRead))
		} else {
			status, out, err = f.FileInterface().ReadAt(
				uint64(bytesToRead),
				uint64(int64(ptr)+off),
			)
		}
		if err != nil {
			return ptr, err
		} else if status != zx.ErrOk {
			return ptr, zx.Error{Status: status, Text: "io.file"}
		}
		if len(out) == 0 {
			return ptr, nil
		}
		copy(data[ptr:ptr+len(out)], out)
		ptr += len(out)
		// Stop at short read.
		if len(out) < bytesToRead {
			return ptr, nil
		}
	}
	return ptr, nil
}

// Read reads data from the internally held offset in the File.
func (f *File) Read(data []byte) (int, error) {
	return f.read(data, -1)
}

// ReadAt reads data at an offset in a File.
func (f *File) ReadAt(data []byte, off int64) (int, error) {
	return f.read(data, off)
}

// write writes data to a file. If off == -1 then the write occurs at
// whatever the seek offset is.
func (f *File) write(data []byte, off int64) (int, error) {
	ptr := 0
	for ptr < len(data) {
		bytesToWrite := int(io.KMaxBuf)
		if len(data)-ptr < int(io.KMaxBuf) {
			bytesToWrite = len(data) - ptr
		}
		var status zx.Status
		var written uint64
		var err error
		if off == -1 {
			status, written, err = f.FileInterface().Write(
				data[ptr : ptr+bytesToWrite],
			)
		} else {
			status, written, err = f.FileInterface().WriteAt(
				data[ptr:ptr+bytesToWrite],
				uint64(int64(ptr)+off),
			)
		}
		if err != nil {
			return ptr, err
		} else if status != zx.ErrOk {
			return ptr, zx.Error{Status: status, Text: "io.file"}
		}
		ptr += int(written)
		// Error on a short write.
		if int(written) < bytesToWrite {
			return ptr, zx.Error{Status: zx.ErrIO, Text: "io.file"}
		}
	}
	return ptr, nil
}

// Write writes data at the internally held offset in the File.
func (f *File) Write(data []byte) (int, error) {
	return f.write(data, -1)
}

// WriteAt writes data at an offset in a File.
func (f *File) WriteAt(data []byte, off int64) (int, error) {
	return f.write(data, off)
}

// Seek moves the read/write head offset of the File.
func (f *File) Seek(offset int64, whence int) (int64, error) {
	status, off, err := f.FileInterface().Seek(offset, io.SeekOrigin(whence))
	if err != nil {
		return -1, err
	} else if status != zx.ErrOk {
		return -1, zx.Error{Status: status, Text: "io.file"}
	}
	return int64(off), nil
}

// Truncate truncates a File.
func (f *File) Truncate(length uint64) error {
	status, err := f.FileInterface().Truncate(length)
	if err != nil {
		return err
	} else if status != zx.ErrOk {
		return zx.Error{Status: status, Text: "io.file"}
	}
	return nil
}
