// Copyright 2017 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 os

// #cgo fuchsia CFLAGS: -I${SRCDIR}/../../../../../zircon/system/ulib/fdio/include
// #cgo fuchsia LDFLAGS: -lfdio
//
// #include <lib/fdio/fd.h>
// #include <lib/fdio/spawn.h>
// #include <stdlib.h>
// #include <unistd.h>
// #include <zircon/syscalls/object.h>
// #include <zircon/types.h>
//
// static int fsa_get_local_fd(fdio_spawn_action_t *fsa) { return fsa->fd.local_fd; }
// static int fsa_get_target_fd(fdio_spawn_action_t *fsa) { return fsa->fd.target_fd; }
//
// static void fsa_set_local_fd(fdio_spawn_action_t *fsa, int fd) { fsa->fd.local_fd = fd; }
// static void fsa_set_target_fd(fdio_spawn_action_t *fsa, int fd) { fsa->fd.target_fd = fd; }
import "C"

import (
	"errors"
	"syscall"
	"syscall/zx"
	"syscall/zx/zxwait"
	"unsafe"
)

func makeCStringArray(s []string) []*C.char {
	ret := make([]*C.char, len(s)+1)
	for i, s := range s {
		ret[i] = (*C.char)(C.CString(s))
	}
	ret[len(ret)-1] = nil
	return ret
}

func freeCStringArray(a []*C.char) {
	for i := range a {
		if a[i] != nil {
			C.free(unsafe.Pointer(a[i]))
		}
	}
}

// asLibfdioFD returns a File as a libfdio file descriptor.
func asLibfdioFD(f *File) (int, error) {
	m := syscall.FDIOForFD(int(f.Fd()))
	if m == nil {
		return -1, ErrInvalid
	}

	mCopy, err := m.Clone()
	if err != nil {
		return -1, err
	}
	handles := mCopy.Handles()

	var fd C.int
	status := zx.Status(C.fdio_fd_create(C.zx_handle_t(handles[0]), &fd))
	if status != zx.ErrOk {
		return -1, errors.New("fdio_fd_create failed")
	}
	return int(fd), nil
}

func fdioSpawnActions(attr *ProcAttr) (actions []C.fdio_spawn_action_t, err error) {
	defer func() {
		if err != nil {
			for _, action := range actions {
				C.close(C.fsa_get_local_fd(&action))
			}
		}
	}()

	for i, f := range attr.Files {
		if f == nil {
			continue
		}
		fd, err := asLibfdioFD(f)
		if err != nil {
			return nil, err
		}
		action := C.fdio_spawn_action_t{action: C.FDIO_SPAWN_ACTION_TRANSFER_FD}
		C.fsa_set_local_fd(&action, C.int(fd))
		C.fsa_set_target_fd(&action, C.int(i))
		actions = append(actions, action)
	}

	return actions, nil
}

func fdioStartProcess(name string, argv []string, attr *ProcAttr) (zx.Handle, error) {
	env := attr.Env
	if env == nil {
		env = Environ()
	}
	if attr.Dir != "" {
		found := false
		for i, s := range env {
			const prefix = "PWD="
			// strings.HasPrefix
			if len(s) >= len(prefix) && s[:len(prefix)] == prefix {
				found = true
				env[i] = "PWD=" + attr.Dir
				break
			}
		}
		if !found {
			env = append(env, "PWD="+attr.Dir)
		}
	}

	nameC := C.CString(name)
	defer C.free(unsafe.Pointer(nameC))
	argvC := makeCStringArray(argv)
	defer freeCStringArray(argvC)
	envC := makeCStringArray(env)
	defer freeCStringArray(envC)

	actions, err := fdioSpawnActions(attr)
	if err != nil {
		return 0, err
	}

	var actions0 *C.fdio_spawn_action_t
	if len(actions) > 0 {
		actions0 = &actions[0]
	}

	var h C.zx_handle_t
	var errmsg [C.FDIO_SPAWN_ERR_MSG_MAX_LENGTH]C.char
	status := zx.Status(C.fdio_spawn_etc(
		C.ZX_HANDLE_INVALID,
		C.FDIO_SPAWN_CLONE_JOB|C.FDIO_SPAWN_DEFAULT_LDSVC|C.FDIO_SPAWN_CLONE_NAMESPACE, // TODO(mdempsky): Flags.
		nameC,
		&argvC[0],
		&envC[0],
		C.size_t(len(actions)),
		actions0,
		&h,
		&errmsg[0],
	))
	if status != zx.ErrOk {
		return 0, errors.New("fdio_spawn_etc: " + itoa(int(status)) + ": " + charsAsString(errmsg[:]))
	}
	return zx.Handle(h), nil
}

func charsAsString(s []C.char) string {
	var x []byte
	for _, c := range s {
		if c == 0 {
			break
		}
		x = append(x, byte(c))
	}
	return string(x)
}

func (p *Process) kill() error {
	procHandle := zx.Handle(p.handle)
	status := zx.Sys_task_kill(procHandle)
	if status != zx.ErrOk {
		return errors.New("kill error: " + itoa(int(status)))
	}
	return nil
}

func (p *Process) wait() (ps *ProcessState, err error) {
	procHandle := zx.Handle(p.handle)
	_, err = zxwait.Wait(procHandle, zx.SignalTaskTerminated, zx.TimensecInfinite)
	if err != nil {
		return nil, err
	}
	procInfo := C.zx_info_process_t{}
	status := zx.Sys_object_get_info(procHandle, zx.ObjectInfoProcess, unsafe.Pointer(&procInfo), C.sizeof_zx_info_process_t, nil, nil)
	if status != zx.ErrOk {
		return nil, errors.New("error retrieving process info: " + itoa(int(status)))
	}
	defer p.Release()
	return &ProcessState{int(procInfo.return_code)}, nil
}
