// 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 (
	"syscall/zx"
	"unsafe"
)

type mOS struct{}

type sigset struct{}

//go:nosplit
func getRandomData(r []byte) {
	zx.RandRead(r)
}

//go:nosplit
func futexsleep(addr *uint32, val uint32, ns int64) {
	deadline := zx.Sys_deadline_after(zx.Duration(ns))
	if ns < 0 {
		deadline = zx.Time(zx.TimensecInfinite)
	}
	zx.Sys_futex_wait((*int)(unsafe.Pointer(addr)), int32(val), deadline)
}

//go:nosplit
func futexwakeup(addr *uint32, cnt uint32) {
	zx.Sys_futex_wake((*int)(unsafe.Pointer(addr)), cnt)
}

//go:nosplit
func osyield() {
	zx.Sys_nanosleep(0)
}

// cgocallm0 calls a C function on the current stack.
//
// It is intended for use inside functions like osinit that run
// before mstart directly on an OS thread stack.
//
// If in doubt, do not use.
func cgocallm0(fn, arg unsafe.Pointer)

func osinit() {
	if _cgo_get_initial_handles != nil {
		cgocallm0(_cgo_get_initial_handles, unsafe.Pointer(&fdioHandles))
		for i := 0; i < 3; i = i + 1 {
			for j := 0; j < int(fdioHandles.stdioCloneNumHandles[i]); j = j + 1 {
				zx.StdioHandles[i][j] = fdioHandles.stdioClones[i*3+j]
			}
			zx.StdioHandleTypes[i] = int(fdioHandles.stdioCloneTypes[i])
		}
		zx.ProcHandle = zx.Handle(fdioHandles.processSelf)
		zx.VMARRoot = zx.VMAR(fdioHandles.vmarRootSelf)
	} else {
		// TODO: implement cgo-less init
		println("runtime: no fuchsia process handle without cgo yet")
		exit(2)
	}

	ncpu = int32(zx.Sys_system_get_num_cpus())
	physPageSize = 4096
}

func parseRootNS() {
	if fdioHandles.rootNSNumHandles > 0 {
		const maxHandleCount = 1 << 20 // arbitrary
		paths := (*(*[maxHandleCount]*byte)(unsafe.Pointer(fdioHandles.rootNSPaths)))[:fdioHandles.rootNSNumHandles]
		handles := (*(*[maxHandleCount]zx.Handle)(unsafe.Pointer(fdioHandles.rootNSHandles)))[:fdioHandles.rootNSNumHandles]
		zx.RootNSMap = make(map[string]zx.Handle)
		for i, p := range paths {
			zx.RootNSMap[gostring(p)] = handles[i]
		}
	}
}

// Filled in by runtime/cgo when linked into binary.
var _cgo_get_initial_handles unsafe.Pointer // pointer to C function

func minit() {
}

//go:nosplit
func unminit() {
	// TODO
}

func sigpanic() {
	// TODO
}

func mpreinit(mp *m) {
	// TODO
}

//go:nosplit
func msigsave(mp *m) {
	// TODO
}

//go:nosplit
func msigrestore(sigmask sigset) {
	// TODO
}

func initsig(preinit bool) {
	// TODO
}

//go:nosplit
func sigblock() {
	// TODO
}

func sigenable(sig uint32) {
	// TODO
}

func sigdisable(sig uint32) {
	// TODO
}

func sigignore(sig uint32) {
	// TODO
}

func crash() {
	*(*int32)(nil) = 0
}

func threadinit(mp *m)

var gothreadname = []byte("gothread")

//go:nowritebarrier
func newosproc(mp *m) {
	stk := unsafe.Pointer(mp.g0.stack.hi)
	p := zx.Handle(0) // TODO: only works due to temporary hack in zircon
	var h zx.Handle
	status := zx.Sys_thread_create(p, &gothreadname[0], uint(len(gothreadname)), 0, &h)
	if status < 0 {
		println("runtime: newosproc zx.Sys_thread_create failed:", h)
		exit(2)
	}

	status = zx.Sys_thread_start(h, zx.Vaddr(funcPC(threadinit)), zx.Vaddr(stk), uintptr(unsafe.Pointer(mp)), 0)
	if status < 0 {
		println("runtime: newosproc zx.Sys_thread_start failed:", h)
		exit(2)
	}
}

type zx_proc_args struct {
	protocol        uint32
	version         uint32
	handle_info_off uint32
	args_off        uint32
	args_num        uint32
}

type zx_proc_info struct {
	magic         uint32
	version       uint32
	next_tls_slot uint32
	proc_args     *zx_proc_args
	handle        *zx.Handle
	handle_info   *uint32
	handle_count  int32
	argv          **byte
	argc          int32
}

type zx_tls_root struct {
	self     *zx_tls_root
	proc     *zx_proc_info
	magic    uint32
	flags    uint16
	maxslots uint16
	slots    [8]uintptr // has length maxslots
}

func resetcpuprofiler(hz int32) {
	// TODO
}

// fdio_init matches a Go struct of the same name in gcc_fdio.c.
type fdio_init struct {
	stdioClones          [9]zx.Handle // 3 * fdio.MaxHandles
	stdioCloneNumHandles [3]uint32
	stdioCloneTypes      [3]uint32
	processSelf          zx.Handle
	vmarRootSelf         zx.Handle
	_                    int32
	envlen               int32
	environ              **byte
	_                    int32
	rootNSNumHandles     int32
	rootNSHandles        *zx.Handle
	rootNSPaths          **byte
}

var fdioHandles fdio_init

func goenvs() {
	if _cgo_get_initial_handles != nil {
		const maxEnvSize = 1 << 20 // arbitrary
		envp := (*(*[maxEnvSize]*byte)(unsafe.Pointer(fdioHandles.environ)))[:fdioHandles.envlen]
		envs = make([]string, len(envp))
		for i, e := range envp {
			envs[i] = gostring(e)
		}
		// TODO: find a better place to call this
		parseRootNS()
	} else {
		// TODO: implement cgo-less init
		println("runtime: no fuchsia process handle without cgo yet")
		exit(2)
	}
}

const _NSIG = 65 // TODO

//go:nosplit
func nanotime() int64 {
	const ZX_CLOCK_MONOTONIC = 0
	return int64(zx.Sys_clock_get(ZX_CLOCK_MONOTONIC))
}

//go:linkname time_now time.now
//go:nosplit
func time_now() (sec int64, nsec int32, mono int64) {
	const ZX_CLOCK_UTC = 1
	x := int64(zx.Sys_clock_get(ZX_CLOCK_UTC))
	return int64(x / 1e9), int32(x % 1e9), nanotime() - startNano
}

func unixnanotime() int64 {
	return nanotime()
}

var logger zx.Handle
var logBufferArray [1024]byte
var logBufferN int

//go:nosplit
func write(fd uintptr, buf unsafe.Pointer, n int32) int32 {
	if fd == 1 || fd == 2 {
		// This initialization mechanism is not thread-safe, but if the only calls to 'write' with
		// these file descriptors come from print, they will already be serialized by a lock in
		// print's implementation.
		if logger <= 0 {
			zx.Sys_debuglog_create(0, 0, &logger)
			logBufferN = 0
		}
		if logger > 0 {
			// Sys_log_write adds a newline to output buffers. To prevent fragmented logs, we buffer
			// output until a newline character is encountered.
			logBufferN += copy(logBufferArray[logBufferN:], (*[1 << 30]byte)(buf)[:n])
			if logBufferArray[logBufferN-1] == '\n' {
				status := zx.Sys_log_write(logger, uint32(logBufferN), unsafe.Pointer(&logBufferArray[0]), 0)
				// Flush buffer, regardless of status returned from write
				logBufferN = 0
				if status < 0 {
					return int32(status)
				}
			}
		}
	}
	// TODO
	return n
}

//go:nosplit
func exit(code int32) {
	zx.Sys_process_exit(int64(code))
}

//go:nosplit
func usleep(usec uint32) {
	zx.Sys_nanosleep(zx.Sys_deadline_after(zx.Duration(usec * 1000)))
}

func signame(sig uint32) string {
	return "unknown_sig" // TODO
}

// zircon_mktls
//go:nosplit
func zircon_mktls() {
	// TODO
}

//go:nosplit
func zircon_settls(val uintptr) {
	// TODO: should call zx_set_object_property with property ZX_PROP_REGISTER_FS in amd64 or
	// ZX_PROP_REGISTER_CP15 on arm.
}

//go:linkname os_sigpipe os.sigpipe
func os_sigpipe() {
	// TODO
}

// gsignalStack is unused on fuchsia
type gsignalStack struct{}

func exitThread(wait *uint32)        {}
func setProcessCPUProfiler(hz int32) {}
func setThreadCPUProfiler(hz int32)  {}

//go:nosplit
//go:nowritebarrierrec
func clearSignalHandlers() {}
