#include <dispatch/dispatch.h>
#include <xpc/xpc.h>
#include <xpc/connection.h>
#include <Block.h>
#include <stdlib.h>
#include <stdio.h>

#include "_cgo_export.h"

//
// types and errors are implemented as macros
// create some real objects to make them accessible to Go
//
xpc_type_t TYPE_ERROR = XPC_TYPE_ERROR;

xpc_type_t TYPE_ARRAY = XPC_TYPE_ARRAY;
xpc_type_t TYPE_DATA = XPC_TYPE_DATA;
xpc_type_t TYPE_DICT = XPC_TYPE_DICTIONARY;
xpc_type_t TYPE_INT64 = XPC_TYPE_INT64;
xpc_type_t TYPE_STRING = XPC_TYPE_STRING;
xpc_type_t TYPE_UUID = XPC_TYPE_UUID;

xpc_object_t ERROR_CONNECTION_INVALID = (xpc_object_t) XPC_ERROR_CONNECTION_INVALID;
xpc_object_t ERROR_CONNECTION_INTERRUPTED = (xpc_object_t) XPC_ERROR_CONNECTION_INTERRUPTED;
xpc_object_t ERROR_CONNECTION_TERMINATED = (xpc_object_t) XPC_ERROR_TERMINATION_IMMINENT;

const ptr_to_uuid_t ptr_to_uuid(void *p) { return (ptr_to_uuid_t)p; }


//
// connect to XPC service
//
xpc_connection_t XpcConnect(char *service, void *ctx) {
    dispatch_queue_t queue = dispatch_queue_create(service, 0);
    xpc_connection_t conn = xpc_connection_create_mach_service(service, queue, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);

    // making a local copy, that should be made "persistent" with the following Block_copy
    GoInterface ictx = *((GoInterface*)ctx);

    xpc_connection_set_event_handler(conn,
        Block_copy(^(xpc_object_t event) {
            handleXpcEvent(event, (void *)&ictx);
        })
    );

    xpc_connection_resume(conn);
    return conn;
}

void XpcSendMessage(xpc_connection_t conn, xpc_object_t message, bool release, bool reportDelivery) {
    xpc_connection_send_message(conn,  message);
    xpc_connection_send_barrier(conn, ^{
        // Block is invoked on connection's target queue
        // when 'message' has been sent.
        if (reportDelivery) { // maybe this could be a callback
            puts("message delivered");
        }
    });
    if (release) {
        xpc_release(message);
    }
}

void XpcArrayApply(void *v, xpc_object_t arr) {
  xpc_array_apply(arr, ^bool(size_t index, xpc_object_t value) {
    arraySet(v, index, value);
    return true;
  });
}

void XpcDictApply(void *v, xpc_object_t dict) {
  xpc_dictionary_apply(dict, ^bool(const char *key, xpc_object_t value) {
    dictSet(v, (char *)key, value);
    return true;
  });
}

void XpcUUIDGetBytes(void *v, xpc_object_t uuid) {
   const uint8_t *src = xpc_uuid_get_bytes(uuid);
   uint8_t *dest = (uint8_t *)v;

   for (int i=0; i < sizeof(uuid_t); i++) {
     dest[i] = src[i];
   }
}
