// Copyright 2015 The Chromium 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 system

//#include "c_allocators.h"
//#include "mojo/public/c/system/core.h"
import "C"
import (
	"reflect"
	"sync"
	"unsafe"
)

// core is an instance of the Mojo system APIs implementation.
var core coreImpl

// Core is an interface giving access to the base operations.
// See |src/mojo/public/c/system/core.h| for the underlying api.
type Core interface {
	// AcquireNativeHandle acquires a handle from the native side. The handle
	// will be owned by the returned object and must not be closed outside of
	// it.
	AcquireNativeHandle(handle MojoHandle) UntypedHandle

	// GetTimeTicksNow returns a monotonically increasing platform dependent
	// tick count representing "right now". Resolution depends on the system
	// configuration.
	GetTimeTicksNow() MojoTimeTicks

	// WaitMany behaves as if Wait were called on each handle/signal pair
	// simultaneously and completing when the first Wait would complete.
	// Notes about return values:
	//   |index| can be -1 if the error returned was not caused by a
	//       particular handle. For example, the error MOJO_RESULT_DEADLINE_EXCEEDED
	//       is not related to a particular handle.
	//   |states| can be nil if the signal array could not be returned. This can
	//       happen with errors such as MOJO_RESULT_INVALID_ARGUMENT.
	WaitMany(handles []Handle, signals []MojoHandleSignals, deadline MojoDeadline) (result MojoResult, index int, states []MojoHandleSignalsState)

	// CreateDataPipe creates a data pipe which is a unidirectional
	// communication channel for unframed data. On success, returns a
	// handle to the producer and consumer of the data pipe.
	CreateDataPipe(opts *DataPipeOptions) (MojoResult, ProducerHandle, ConsumerHandle)

	// CreateMessagePipe creates a message pipe which is a bidirectional
	// communication channel for framed data (i.e., messages). Messages
	// can contain plain data and/or Mojo handles. On success, it returns
	// handles to the two endpoints of the message pipe.
	CreateMessagePipe(opts *MessagePipeOptions) (MojoResult, MessagePipeHandle, MessagePipeHandle)

	// CreateSharedBuffer creates a buffer of size numBytes that can be
	// shared between applications. One must call MapBuffer to access
	// the buffer.
	CreateSharedBuffer(opts *SharedBufferOptions, numBytes uint64) (MojoResult, SharedBufferHandle)
}

// coreImpl is an implementation of the Mojo system APIs.
type coreImpl struct {
	// Protects from making parallel non-blocking mojo cgo calls.
	mu sync.Mutex
}

// GetCore returns singleton instance of the Mojo system APIs implementation.
//
// The implementation uses cgo to call native mojo APIs implementation. Each cgo
// call uses a separate thread for execution. To limit the number of used
// threads all non-blocking system calls (i.e. all system calls except |Wait|
// and |WaitMany|) on this implementation and on handles returned by this
// implementation are protected by a mutex so that if you make two parallel
// system calls one will wait for another to finish before executing.
// However, |Wait| and |WaitMany| are not protected by a mutex and each parallel
// call will use a separate thread. To reduce number of threads used for |Wait|
// calls prefer to use |WaitMany|.
func GetCore() Core {
	return &core
}

func (impl *coreImpl) acquireCHandle(handle C.MojoHandle) UntypedHandle {
	return impl.AcquireNativeHandle(MojoHandle(handle))
}

func (impl *coreImpl) AcquireNativeHandle(handle MojoHandle) UntypedHandle {
	return &untypedHandleImpl{baseHandle{impl, handle}}
}

func (impl *coreImpl) GetTimeTicksNow() MojoTimeTicks {
	impl.mu.Lock()
	defer impl.mu.Unlock()

	return MojoTimeTicks(C.MojoGetTimeTicksNow())
}

func (impl *coreImpl) WaitMany(handles []Handle, signals []MojoHandleSignals, deadline MojoDeadline) (result MojoResult, index int, states []MojoHandleSignalsState) {
	l := len(handles)
	if l == 0 {
		result = MojoResult(C.MojoWaitMany(nil, nil, 0, deadline.cValue(), nil, nil))
		index = -1
		return
	}
	cParams := C.MallocWaitManyParams(C.uint32_t(l))
	defer C.FreeWaitManyParams(cParams)
	cHandles := *(*[]MojoHandle)(newUnsafeSlice(unsafe.Pointer(cParams.handles), l))
	cStates := *(*[]C.struct_MojoHandleSignalsState)(newUnsafeSlice(unsafe.Pointer(cParams.states), l))
	for i := 0; i < l; i++ {
		cHandles[i] = handles[i].NativeHandle()
		cStates[i] = C.struct_MojoHandleSignalsState{}
	}
	cSignals := *(*[]MojoHandleSignals)(newUnsafeSlice(unsafe.Pointer(cParams.signals), l))
	copy(cSignals, signals)
	// Set "-1" using the instructions from http://blog.golang.org/constants
	*cParams.index = ^C.uint32_t(0)

	result = MojoResult(C.MojoWaitMany(cParams.handles, cParams.signals, C.uint32_t(l), deadline.cValue(), cParams.index, cParams.states))
	// Explicitly convert *cParams.index to int32 type as int has 32 or 64 bits
	// depending on system configuration.
	index = int(int32(*cParams.index))
	if result != MOJO_RESULT_INVALID_ARGUMENT && result != MOJO_RESULT_RESOURCE_EXHAUSTED {
		for _, cState := range cStates {
			states = append(states, cState.goValue())
		}
	}
	return
}

func (impl *coreImpl) CreateDataPipe(opts *DataPipeOptions) (MojoResult, ProducerHandle, ConsumerHandle) {
	impl.mu.Lock()
	defer impl.mu.Unlock()

	cParams := C.MallocCreateDataPipeParams()
	defer C.FreeCreateDataPipeParams(cParams)
	result := C.MojoCreateDataPipe(opts.cValue(cParams.opts), cParams.producer, cParams.consumer)
	producer := impl.acquireCHandle(*cParams.producer).ToProducerHandle()
	consumer := impl.acquireCHandle(*cParams.consumer).ToConsumerHandle()
	return MojoResult(result), producer, consumer
}

func (impl *coreImpl) CreateMessagePipe(opts *MessagePipeOptions) (MojoResult, MessagePipeHandle, MessagePipeHandle) {
	impl.mu.Lock()
	defer impl.mu.Unlock()

	cParams := C.MallocCreateMessagePipeParams()
	defer C.FreeCreateMessagePipeParams(cParams)
	result := C.MojoCreateMessagePipe(opts.cValue(cParams.opts), cParams.handle0, cParams.handle1)
	handle0 := impl.acquireCHandle(*cParams.handle0).ToMessagePipeHandle()
	handle1 := impl.acquireCHandle(*cParams.handle1).ToMessagePipeHandle()
	return MojoResult(result), handle0, handle1
}

func (impl *coreImpl) CreateSharedBuffer(opts *SharedBufferOptions, numBytes uint64) (MojoResult, SharedBufferHandle) {
	impl.mu.Lock()
	defer impl.mu.Unlock()

	cParams := C.MallocCreateSharedBufferParams()
	defer C.FreeCreateSharedBufferParams(cParams)
	result := C.MojoCreateSharedBuffer(opts.cValue(cParams.opts), C.uint64_t(numBytes), cParams.handle)
	return MojoResult(result), impl.acquireCHandle(*cParams.handle).ToSharedBufferHandle()
}

func newUnsafeSlice(ptr unsafe.Pointer, length int) unsafe.Pointer {
	header := &reflect.SliceHeader{
		Data: uintptr(ptr),
		Len:  length,
		Cap:  length,
	}
	return unsafe.Pointer(header)
}

func unsafeByteSlice(ptr unsafe.Pointer, length int) []byte {
	return *(*[]byte)(newUnsafeSlice(ptr, length))
}
