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

package fidl

import (
	"encoding/binary"
	"math"
	"reflect"
	"syscall/zx"
)

const (
	allocPresent uint64 = math.MaxUint64
	noAlloc             = 0
)

const (
	handlePresent uint32 = math.MaxUint32
	noHandle             = 0
)

const (
	maxOutOfLineDepth = 32
)

var (
	// TODO(mknyszek): Add support here for process, thread, job, resource,
	// interrupt, eventpair, fifo, guest, and time once these are actually
	// supported in the Go runtime.
	handleType           reflect.Type = reflect.TypeOf(zx.Handle(0))
	channelType                       = reflect.TypeOf(zx.Channel(0))
	logType                           = reflect.TypeOf(zx.Log(0))
	portType                          = reflect.TypeOf(zx.Port(0))
	vmoType                           = reflect.TypeOf(zx.VMO(0))
	eventType                         = reflect.TypeOf(zx.Event(0))
	socketType                        = reflect.TypeOf(zx.Socket(0))
	vmarType                          = reflect.TypeOf(zx.VMAR(0))
	interfaceRequestType              = reflect.TypeOf(InterfaceRequest{})
	proxyType                         = reflect.TypeOf(ChannelProxy{})
)

// isHandleType returns true if the reflected type is a Fuchsia handle type.
func isHandleType(t reflect.Type) bool {
	switch t {
	case handleType:
		fallthrough
	case channelType:
		fallthrough
	case logType:
		fallthrough
	case portType:
		fallthrough
	case vmoType:
		fallthrough
	case eventType:
		fallthrough
	case socketType:
		fallthrough
	case vmarType:
		return true
	}
	return false
}

// align increases size such that size is aligned to bytes, and returns the new size.
//
// bytes must be a power of 2.
func align(size, bytes int) int {
	alignmentMask := (bytes - 1)
	return (size + alignmentMask) & ^alignmentMask
}

// encoder represents the encoding context that is necessary to maintain across
// recursive calls within the same FIDL object.
type encoder struct {
	// buffer represents the output buffer that the encoder writes into.
	buffer []byte

	// handleDispositions are the handle dispositions discovered when traversing
	// the FIDL data structure. They are referenced from within the serialized
	// data structure in buffer.
	handleDispositions []zx.HandleDisposition
}

// Allocate a new out of line object of the specified size for encoding.
// Returns two values: the starting offset of the new object in the buffer and
// an error indicating that a new object could not be allocated.
func (e *encoder) newObject(size, currentDepth int) (int, error) {
	if currentDepth > maxOutOfLineDepth {
		return 0, newExpectError(ErrExceededMaxOutOfLineDepth, maxOutOfLineDepth, currentDepth+1)
	}
	size = align(size, 8)
	start := len(e.buffer)
	e.buffer = append(e.buffer, make([]byte, size)...)
	return start, nil
}

// writeUint64 writes a uint64 to the buffer at the next 8-byte aligned position.
func (e *encoder) writeUint64(offset int, val uint64) {
	binary.LittleEndian.PutUint64(e.buffer[offset:], val)
}

// writeUint32 writes a uint32 to the buffer at the next 4-byte aligned position.
func (e *encoder) writeUint32(offset int, val uint32) {
	binary.LittleEndian.PutUint32(e.buffer[offset:], val)
}

// writeUint16 writes a uint16 to the buffer at the next 2-byte aligned position.
func (e *encoder) writeUint16(offset int, val uint16) {
	binary.LittleEndian.PutUint16(e.buffer[offset:], val)
}

// writeUint8 writes a uint8 to the buffer.
func (e *encoder) writeUint8(offset int, val uint8) {
	e.buffer[offset] = val
}

// decoder represents the decoding context that is necessary to maintain
// across recursive calls within the same FIDL object.
type decoder struct {
	// nextObject is the byte index of the next out-of-line object in buffer.
	nextObject int

	// buffer represents the buffer we're decoding from.
	buffer []byte

	// handleInfos represents the input untyped handles we're decoding.
	// These objects contain additional information on rights.
	handleInfos []zx.HandleInfo
}

// Allocate a new out of line object of the specified size for decoding.
// Returns two values: the starting offset of the new object in the buffer and
// an error indicating that a new object could not be allocated.
func (d *decoder) newObject(size, currentDepth int) (int, error) {
	if currentDepth > maxOutOfLineDepth {
		return 0, newExpectError(ErrExceededMaxOutOfLineDepth, maxOutOfLineDepth, currentDepth+1)
	}
	start := d.nextObject
	end := start + align(size, 8)
	if end > len(d.buffer) {
		return 0, ErrPayloadTooSmall
	}
	for i := d.nextObject + size; i < end; i++ {
		if d.buffer[i] != 0 {
			return 0, newValueError(ErrNonZeroPadding, d.buffer[i])
		}
	}
	d.nextObject = end
	return start, nil
}

// readUint64 reads a uint64 from the buffer.
func (d *decoder) readUint64(offset int) uint64 {
	return binary.LittleEndian.Uint64(d.buffer[offset:])
}

// readUint32 reads a uint32 from the buffer.
func (d *decoder) readUint32(offset int) uint32 {
	return binary.LittleEndian.Uint32(d.buffer[offset:])
}

// readUint16 reads a uint16 from the buffer.
func (d *decoder) readUint16(offset int) uint16 {
	return binary.LittleEndian.Uint16(d.buffer[offset:])
}

// readUint8 reads a uint8 from the buffer.
func (d *decoder) readUint8(offset int) uint8 {
	return d.buffer[offset]
}
