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

package runtime

import (
	"unsafe"
)

const (
	permRead  = 1 << 0
	permWrite = 1 << 1

	propName = 3
)

//go:linkname sys_vmar_unmap syscall/zx.Sys_vmar_unmap
func sys_vmar_unmap(h uint32, addr unsafe.Pointer, l uint64) int32

//go:linkname sys_vmo_create syscall/zx.Sys_vmo_create
//go:noescape
func sys_vmo_create(size uint64, options uint32, out *uint32) int32

//go:linkname sys_object_set_property syscall/zx.Sys_object_set_property
//go:noescape
func sys_object_set_property(handle uint32, property uint32, value unsafe.Pointer, value_size uint) int32

//go:linkname sys_vmar_map syscall/zx.Sys_vmar_map
//go:noescape
func sys_vmar_map(handle uint32, options uint32, vmar_offset uint64, vmo uint32, vmo_offset uint64, len uint64, mapped_addr *unsafe.Pointer) int32

//go:linkname sys_handle_close syscall/zx.Sys_handle_close
//go:noescape
func sys_handle_close(handle uint32) int32

//go:linkname sys_vmar_protect syscall/zx.Sys_vmar_protect
func sys_vmar_protect(handle uint32, options uint32, addr unsafe.Pointer, len uint64) int32

//go:nosplit
func sysAlloc(n uintptr, sysStat *uint64) unsafe.Pointer {
	var p unsafe.Pointer
	sysMmap(unsafe.Pointer(&p), n, permRead|permWrite)
	if uintptr(p) < 4096 {
		println("runtime: sysMmap failed n=", n)
		exit(2)
	}
	mSysStatInc(sysStat, n)
	return p
}

func sysUnused(v unsafe.Pointer, n uintptr) {
	// TODO(dho): Implement this based on ZX_VMO_OP_DECOMMIT
}

func sysUsed(v unsafe.Pointer, n uintptr) {
	// TODO(dho): Maybe implement this based on ZX_VMO_OP_COMMIT
}

//go:nosplit
func sysFree(v unsafe.Pointer, n uintptr, sysStat *uint64) {
	mSysStatDec(sysStat, n)
	if status := sys_vmar_unmap(fdioHandles.vmarRootSelf, v, uint64(n)); status != 0 {
		println("runtime: sys_vmar_unmap failed: ", status)
	}
}

func sysMmap(ptr unsafe.Pointer, sz uintptr, flags uint32) {
	var h uint32
	if status := sys_vmo_create(uint64(sz), 0, &h); status != 0 {
		println("runtime: sys_vmo_create failed: ", status)
		exit(2)
	}

	prop := []byte("go-sys-mmap")
	if status := sys_object_set_property(h, propName, unsafe.Pointer(&prop[0]), uint(len(prop))); status != 0 {
		println("runtime: sys_object_set_property failed: ", status)
		exit(2)
	}

	if status := sys_vmar_map(fdioHandles.vmarRootSelf, flags, 0, h, 0, uint64(sz), (*unsafe.Pointer)(ptr)); status != 0 {
		println("runtime: sys_vmar_map failed: ", status)
		exit(2)
	}

	if status := sys_handle_close(h); status != 0 {
		println("runtime: sys_handle_close failed: ", status)
		exit(2)
	}
}

func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer {
	p := v
	sysMmap(unsafe.Pointer(&p), n, 0)
	return p
}

func sysFault(v unsafe.Pointer, n uintptr) {
	println("TODO sysFault")
}

func sysMap(v unsafe.Pointer, n uintptr, sysStat *uint64) {
	mSysStatInc(sysStat, n)

	if status := sys_vmar_protect(fdioHandles.vmarRootSelf, permRead|permWrite, v, uint64(n)); status != 0 {
		println("runtime: sys_vmar_protect failed: ", status)
		exit(2)
	}
}
