// A tid is 62 bits.
func createTID() uint64 {
	buf := cryptonacl.Random(8)

	// Clear the two most significant bits.
	buf[7] &= 0x3f

	return binary.LittleEndian.Uint64(buf)
}
func handleSyscall(conn *websocket.Conn, command map[string]interface{}) ([]byte, error) {
	switch command["command"] {
	case "advertise":
		serviceName, ok := command["service"].(string)
		if !ok {
			return jsonError("service is required as a string")
		}

		reqid, ok := command["reqid"].(string)
		if !ok {
			return jsonError("reqid is required as a string")
		}

		service, err := mlt.Advertise(serviceName)
		if err != nil {
			return jsonError(err.Error())
		}

		services[serviceConn{service: serviceName, conn: conn}] = service

		return json.Marshal(map[string]string{
			"reqid": reqid,
		})
	case "import":
		serviceName, ok := command["service"].(string)
		if !ok {
			return jsonError("service is required as a string")
		}

		reqid, ok := command["reqid"].(string)
		if !ok {
			return jsonError("reqid is required as a string")
		}

		service := services[serviceConn{service: serviceName, conn: conn}]

		if service == nil {
			return jsonError("No service by that name")
		}

		mltConn, err := service.Import()
		if err != nil {
			return jsonError(err.Error())
		}

		cid := strconv.FormatUint(binary.LittleEndian.Uint64(cryptonacl.Random(8)), 36)

		connections[cid] = mltConn

		return json.Marshal(map[string]interface{}{
			"reqid": reqid,
			"cid":   cid,
		})
	case "ipc":
		serviceName, ok := command["service"].(string)
		if !ok {
			return jsonError("service is required as a string")
		}

		address, ok := command["address"].(string)
		if !ok {
			return jsonError("address is required as a string")
		}

		reqid, ok := command["reqid"].(string)
		if !ok {
			return jsonError("reqid is required as a string")
		}

		mltConn, err := mlt.IPC(serviceName, address)
		if err != nil {
			return jsonError(err.Error())
		}

		cid := strconv.FormatUint(binary.LittleEndian.Uint64(cryptonacl.Random(8)), 36)

		connections[cid] = mltConn

		return json.Marshal(map[string]interface{}{
			"reqid": reqid,
			"cid":   cid,
		})
	case "write":
		cid, ok := command["cid"].(string)
		if !ok {
			return jsonError("cid is required as a string")
		}

		data, ok := command["data"].(string)
		if !ok {
			return jsonError("data is required as a string")
		}

		reqid, ok := command["reqid"].(string)
		if !ok {
			return jsonError("reqid is required as a string")
		}

		mltConn := connections[cid]

		if mltConn == nil {
			return jsonError("connection doesn't exist")
		}

		if _, err := mltConn.Write([]byte(data)); err != nil {
			return jsonError(err.Error())
		}

		return json.Marshal(map[string]interface{}{
			"reqid": reqid,
		})
	default:
		return jsonError("Unknown command " + command["command"].(string))
	}
}