// Copyright 2020 The Fuchsia 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 !build_with_native_toolchain
// +build !build_with_native_toolchain

package fifo

import (
	"fmt"
	"reflect"
	"syscall/zx"
	"unsafe"

	"go.uber.org/multierr"
)

// MappedVMO own a VMO and its mapping into process memory. It provides common
// operations for memory mapped VMOs. Closing it will cause the mapped region to
// be unmapped.
type MappedVMO struct {
	vaddr zx.Vaddr
	len   uint64
}

// Close unmaps the mapped VMO region and closes the VMO object.
func (vmo *MappedVMO) Close() error {
	return zx.VMARRoot.Unmap(vmo.vaddr, vmo.len)
}

// GetData returns a slice view into the mapped VMO with offset and length.
// If the provided range is not within bounds of the VMO, GetData panics.
func (vmo *MappedVMO) GetData(offset, len uint64) []byte {
	if offset+len > vmo.len {
		panic(fmt.Sprintf("invalid VMO data range (offset:%d, len:%d) for VMO with %d bytes", offset, len, vmo.len))
	}
	return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
		Data: uintptr(vmo.vaddr) + uintptr(offset),
		Len:  int(len),
		Cap:  int(len),
	}))
}

// GetPointer returns a pointer to the mapped VMO at offset. If the offset is
// not within bounds of the mapped VMO, GetPointer panics.
func (vmo *MappedVMO) GetPointer(offset uint64) unsafe.Pointer {
	if offset > vmo.len {
		panic(fmt.Sprintf("invalid VMO pointer (offset:%d) for VMO with %d bytes", offset, vmo.len))
	}
	return unsafe.Pointer(uintptr(vmo.vaddr) + uintptr(offset))
}

// NewMappedVMO creates a new VMO the given name and size, in bytes, and maps it
// to the process' memory space.
func NewMappedVMO(size uint64, name string) (MappedVMO, zx.VMO, error) {
	vmo, err := zx.NewVMO(size, 0)
	if err != nil {
		return MappedVMO{}, zx.VMO(zx.HandleInvalid), err
	}
	if err := vmo.Handle().SetProperty(zx.PropName, []byte(name)); err != nil {
		err = multierr.Append(err, vmo.Close())
		return MappedVMO{}, zx.VMO(zx.HandleInvalid), err
	}
	mappedVmo, err := MapVMO(vmo)
	if err != nil {
		err = multierr.Append(err, vmo.Close())
		return MappedVMO{}, zx.VMO(zx.HandleInvalid), err
	}
	return mappedVmo, vmo, nil
}

// Len returns the length of the VMO.
func (vmo *MappedVMO) Len() uint64 {
	return vmo.len
}

// MapVMO maps a vmo into the process' memory space. It does not take ownership
// of the VMO.
func MapVMO(vmo zx.VMO) (MappedVMO, error) {
	size, err := vmo.Size()
	if err != nil {
		return MappedVMO{}, err
	}
	vaddr, err := zx.VMARRoot.Map(0, vmo, 0, size, zx.VMFlagPermRead|zx.VMFlagPermWrite)
	if err != nil {
		return MappedVMO{}, err
	}

	return MappedVMO{
		vaddr: vaddr,
		len:   size,
	}, nil
}
