/*
 * installation_proxy.c
 * com.apple.mobile.installation_proxy service implementation.
 *
 * Copyright (c) 2010-2015 Martin Szulecki All Rights Reserved.
 * Copyright (c) 2010-2013 Nikias Bassen, All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>

#ifndef _MSC_VER
#include <unistd.h>
#endif

#include <plist/plist.h>

#include "installation_proxy.h"
#include "property_list_service.h"
#include "common/debug.h"

typedef enum {
	INSTPROXY_COMMAND_TYPE_ASYNC,
	INSTPROXY_COMMAND_TYPE_SYNC
} instproxy_command_type_t;

struct instproxy_status_data {
	instproxy_client_t client;
	plist_t command;
	instproxy_status_cb_t cbfunc;
	void *user_data;
};

/**
 * Converts an error string identifier to a instproxy_error_t value.
 * Used internally to get correct error codes from a response.
 *
 * @param name The error name to convert.
 * @param error_detail Pointer to store error detail text if available. The
 *   caller is reponsible for freeing the allocated buffer after use. If NULL
 *   is passed no error detail will be returned.
 *
 * @return A matching instproxy_error_t error code or
 *   INSTPROXY_E_UNKNOWN_ERROR otherwise.
 */
static instproxy_error_t instproxy_strtoerr(const char* name)
{
	instproxy_error_t err = INSTPROXY_E_UNKNOWN_ERROR;

	if (strcmp(name, "AlreadyArchived") == 0) {
		err = INSTPROXY_E_ALREADY_ARCHIVED;
	} else if (strcmp(name, "APIInternalError") == 0) {
		err = INSTPROXY_E_API_INTERNAL_ERROR;
	} else if (strcmp(name, "ApplicationAlreadyInstalled") == 0) {
		err = INSTPROXY_E_APPLICATION_ALREADY_INSTALLED;
	} else if (strcmp(name, "ApplicationMoveFailed") == 0) {
		err = INSTPROXY_E_APPLICATION_MOVE_FAILED;
	} else if (strcmp(name, "ApplicationSINFCaptureFailed") == 0) {
		err = INSTPROXY_E_APPLICATION_SINF_CAPTURE_FAILED;
	} else if (strcmp(name, "ApplicationSandboxFailed") == 0) {
		err = INSTPROXY_E_APPLICATION_SANDBOX_FAILED;
	} else if (strcmp(name, "ApplicationVerificationFailed") == 0) {
		err = INSTPROXY_E_APPLICATION_VERIFICATION_FAILED;
	} else if (strcmp(name, "ArchiveDestructionFailed") == 0) {
		err = INSTPROXY_E_ARCHIVE_DESTRUCTION_FAILED;
	} else if (strcmp(name, "BundleVerificationFailed") == 0) {
		err = INSTPROXY_E_BUNDLE_VERIFICATION_FAILED;
	} else if (strcmp(name, "CarrierBundleCopyFailed") == 0) {
		err = INSTPROXY_E_CARRIER_BUNDLE_COPY_FAILED;
	} else if (strcmp(name, "CarrierBundleDirectoryCreationFailed") == 0) {
		err = INSTPROXY_E_CARRIER_BUNDLE_DIRECTORY_CREATION_FAILED;
	} else if (strcmp(name, "CarrierBundleMissingSupportedSIMs") == 0) {
		err = INSTPROXY_E_CARRIER_BUNDLE_MISSING_SUPPORTED_SIMS;
	} else if (strcmp(name, "CommCenterNotificationFailed") == 0) {
		err = INSTPROXY_E_COMM_CENTER_NOTIFICATION_FAILED;
	} else if (strcmp(name, "ContainerCreationFailed") == 0) {
		err = INSTPROXY_E_CONTAINER_CREATION_FAILED;
	} else if (strcmp(name, "ContainerP0wnFailed") == 0) {
		err = INSTPROXY_E_CONTAINER_P0WN_FAILED;
	} else if (strcmp(name, "ContainerRemovalFailed") == 0) {
		err = INSTPROXY_E_CONTAINER_REMOVAL_FAILED;
	} else if (strcmp(name, "EmbeddedProfileInstallFailed") == 0) {
		err = INSTPROXY_E_EMBEDDED_PROFILE_INSTALL_FAILED;
	} else if (strcmp(name, "ExecutableTwiddleFailed") == 0) {
		err = INSTPROXY_E_EXECUTABLE_TWIDDLE_FAILED;
	} else if (strcmp(name, "ExistenceCheckFailed") == 0) {
		err = INSTPROXY_E_EXISTENCE_CHECK_FAILED;
	} else if (strcmp(name, "InstallMapUpdateFailed") == 0) {
		err = INSTPROXY_E_INSTALL_MAP_UPDATE_FAILED;
	} else if (strcmp(name, "ManifestCaptureFailed") == 0) {
		err = INSTPROXY_E_MANIFEST_CAPTURE_FAILED;
	} else if (strcmp(name, "MapGenerationFailed") == 0) {
		err = INSTPROXY_E_MAP_GENERATION_FAILED;
	} else if (strcmp(name, "MissingBundleExecutable") == 0) {
		err = INSTPROXY_E_MISSING_BUNDLE_EXECUTABLE;
	} else if (strcmp(name, "MissingBundleIdentifier") == 0) {
		err = INSTPROXY_E_MISSING_BUNDLE_IDENTIFIER;
	} else if (strcmp(name, "MissingBundlePath") == 0) {
		err = INSTPROXY_E_MISSING_BUNDLE_PATH;
	} else if (strcmp(name, "MissingContainer") == 0) {
		err = INSTPROXY_E_MISSING_CONTAINER;
	} else if (strcmp(name, "NotificationFailed") == 0) {
		err = INSTPROXY_E_NOTIFICATION_FAILED;
	} else if (strcmp(name, "PackageExtractionFailed") == 0) {
		err = INSTPROXY_E_PACKAGE_EXTRACTION_FAILED;
	} else if (strcmp(name, "PackageInspectionFailed") == 0) {
		err = INSTPROXY_E_PACKAGE_INSPECTION_FAILED;
	} else if (strcmp(name, "PackageMoveFailed") == 0) {
		err = INSTPROXY_E_PACKAGE_MOVE_FAILED;
	} else if (strcmp(name, "PathConversionFailed") == 0) {
		err = INSTPROXY_E_PATH_CONVERSION_FAILED;
	} else if (strcmp(name, "RestoreContainerFailed") == 0) {
		err = INSTPROXY_E_RESTORE_CONTAINER_FAILED;
	} else if (strcmp(name, "SeatbeltProfileRemovalFailed") == 0) {
		err = INSTPROXY_E_SEATBELT_PROFILE_REMOVAL_FAILED;
	} else if (strcmp(name, "StageCreationFailed") == 0) {
		err = INSTPROXY_E_STAGE_CREATION_FAILED;
	} else if (strcmp(name, "SymlinkFailed") == 0) {
		err = INSTPROXY_E_SYMLINK_FAILED;
	} else if (strcmp(name, "UnknownCommand") == 0) {
		err = INSTPROXY_E_UNKNOWN_COMMAND;
	} else if (strcmp(name, "iTunesArtworkCaptureFailed") == 0) {
		err = INSTPROXY_E_ITUNES_ARTWORK_CAPTURE_FAILED;
	} else if (strcmp(name, "iTunesMetadataCaptureFailed") == 0) {
		err = INSTPROXY_E_ITUNES_METADATA_CAPTURE_FAILED;
	} else if (strcmp(name, "DeviceOSVersionTooLow") == 0) {
		err = INSTPROXY_E_DEVICE_OS_VERSION_TOO_LOW;
	} else if (strcmp(name, "DeviceFamilyNotSupported") == 0) {
		err = INSTPROXY_E_DEVICE_FAMILY_NOT_SUPPORTED;
	} else if (strcmp(name, "PackagePatchFailed") == 0) {
		err = INSTPROXY_E_PACKAGE_PATCH_FAILED;
	} else if (strcmp(name, "IncorrectArchitecture") == 0) {
		err = INSTPROXY_E_INCORRECT_ARCHITECTURE;
	} else if (strcmp(name, "PluginCopyFailed") == 0) {
		err = INSTPROXY_E_PLUGIN_COPY_FAILED;
	} else if (strcmp(name, "BreadcrumbFailed") == 0) {
		err = INSTPROXY_E_BREADCRUMB_FAILED;
	} else if (strcmp(name, "BreadcrumbUnlockFailed") == 0) {
		err = INSTPROXY_E_BREADCRUMB_UNLOCK_FAILED;
	} else if (strcmp(name, "GeoJSONCaptureFailed") == 0) {
		err = INSTPROXY_E_GEOJSON_CAPTURE_FAILED;
	} else if (strcmp(name, "NewsstandArtworkCaptureFailed") == 0) {
		err = INSTPROXY_E_NEWSSTAND_ARTWORK_CAPTURE_FAILED;
	} else if (strcmp(name, "MissingCommand") == 0) {
		err = INSTPROXY_E_MISSING_COMMAND;
	} else if (strcmp(name, "NotEntitled") == 0) {
		err = INSTPROXY_E_NOT_ENTITLED;
	} else if (strcmp(name, "MissingPackagePath") == 0) {
		err = INSTPROXY_E_MISSING_PACKAGE_PATH;
	} else if (strcmp(name, "MissingContainerPath") == 0) {
		err = INSTPROXY_E_MISSING_CONTAINER_PATH;
	} else if (strcmp(name, "MissingApplicationIdentifier") == 0) {
		err = INSTPROXY_E_MISSING_APPLICATION_IDENTIFIER;
	} else if (strcmp(name, "MissingAttributeValue") == 0) {
		err = INSTPROXY_E_MISSING_ATTRIBUTE_VALUE;
	} else if (strcmp(name, "LookupFailed") == 0) {
		err = INSTPROXY_E_LOOKUP_FAILED;
	} else if (strcmp(name, "DictCreationFailed") == 0) {
		err = INSTPROXY_E_DICT_CREATION_FAILED;
	} else if (strcmp(name, "InstallProhibited") == 0) {
		err = INSTPROXY_E_INSTALL_PROHIBITED;
	} else if (strcmp(name, "UninstallProhibited") == 0) {
		err = INSTPROXY_E_UNINSTALL_PROHIBITED;
	} else if (strcmp(name, "MissingBundleVersion") == 0) {
		err = INSTPROXY_E_MISSING_BUNDLE_VERSION;
	}

	return err;
}

/**
 * Locks an installation_proxy client, used for thread safety.
 *
 * @param client The installation_proxy client to lock
 */
static void instproxy_lock(instproxy_client_t client)
{
	debug_info("Locked");
	mutex_lock(&client->mutex);
}

/**
 * Unlocks an installation_proxy client, used for thread safety.
 *
 * @param client The installation_proxy client to lock
 */
static void instproxy_unlock(instproxy_client_t client)
{
	debug_info("Unlocked");
	mutex_unlock(&client->mutex);
}

/**
 * Converts a property_list_service_error_t value to an instproxy_error_t value.
 * Used internally to get correct error codes.
 *
 * @param err A property_list_service_error_t error code
 *
 * @return A matching instproxy_error_t error code,
 *     INSTPROXY_E_UNKNOWN_ERROR otherwise.
 */
static instproxy_error_t instproxy_error(property_list_service_error_t err)
{
	switch (err) {
		case PROPERTY_LIST_SERVICE_E_SUCCESS:
			return INSTPROXY_E_SUCCESS;
		case PROPERTY_LIST_SERVICE_E_INVALID_ARG:
			return INSTPROXY_E_INVALID_ARG;
		case PROPERTY_LIST_SERVICE_E_PLIST_ERROR:
			return INSTPROXY_E_PLIST_ERROR;
		case PROPERTY_LIST_SERVICE_E_MUX_ERROR:
			return INSTPROXY_E_CONN_FAILED;
		case PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT:
			return INSTPROXY_E_RECEIVE_TIMEOUT;
		default:
			break;
	}
	return INSTPROXY_E_UNKNOWN_ERROR;
}

instproxy_error_t instproxy_client_new(idevice_t device, lockdownd_service_descriptor_t service, instproxy_client_t *client)
{
	property_list_service_client_t plistclient = NULL;
	instproxy_error_t err = instproxy_error(property_list_service_client_new(device, service, &plistclient));
	if (err != INSTPROXY_E_SUCCESS) {
		return err;
	}

	instproxy_client_t client_loc = (instproxy_client_t) malloc(sizeof(struct instproxy_client_private));
	client_loc->parent = plistclient;
	mutex_init(&client_loc->mutex);
	client_loc->receive_status_thread = THREAD_T_NULL;

	*client = client_loc;
	return INSTPROXY_E_SUCCESS;
}

instproxy_error_t instproxy_client_start_service(idevice_t device, instproxy_client_t * client, const char* label)
{
	int32_t err = INSTPROXY_E_UNKNOWN_ERROR;
	service_client_factory_start_service(device, INSTPROXY_SERVICE_NAME, (void**)client, label, SERVICE_CONSTRUCTOR(instproxy_client_new), &err);
	return err;
}

instproxy_error_t instproxy_client_free(instproxy_client_t client)
{
	if (!client)
		return INSTPROXY_E_INVALID_ARG;

	property_list_service_client_t parent = client->parent;
	client->parent = NULL;
	if (client->receive_status_thread) {
		debug_info("joining receive_status_thread");
		thread_join(client->receive_status_thread);
		thread_free(client->receive_status_thread);
		client->receive_status_thread = THREAD_T_NULL;
	}
	property_list_service_client_free(parent);
	mutex_destroy(&client->mutex);
	free(client);

	return INSTPROXY_E_SUCCESS;
}

/**
 * Sends a command to the device.
 * Only used internally.
 *
 * @param client The connected installation_proxy client.
 * @param command The command to execute. Required.
 *
 * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if
 *     an error occurred.
 */
static instproxy_error_t instproxy_send_command(instproxy_client_t client, plist_t command)
{
	if (!client || !command)
		return INSTPROXY_E_INVALID_ARG;

	instproxy_error_t res = instproxy_error(property_list_service_send_xml_plist(client->parent, command));

	if (res != INSTPROXY_E_SUCCESS) {
		debug_info("could not send command plist, error %d", res);
		return res;
	}

	return res;
}

/**
 * Internally used function that will synchronously receive messages from
 * the specified installation_proxy until it completes or an error occurs.
 *
 * If status_cb is not NULL, the callback function will be called each time
 * a status update or error message is received.
 *
 * @param client The connected installation proxy client
 * @param status_cb Pointer to a callback function or NULL
 * @param command Operation specificiation in plist. Will be passed to the
 *        status_cb callback.
 * @param user_data Callback data passed to status_cb.
 */
static instproxy_error_t instproxy_receive_status_loop(instproxy_client_t client, plist_t command, instproxy_status_cb_t status_cb, void *user_data)
{
	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;
	int complete = 0;
	plist_t node = NULL;
	char* command_name = NULL;
	char* status_name = NULL;
	char* error_name = NULL;
	char* error_description = NULL;
	uint64_t error_code = 0;
#ifndef STRIP_DEBUG_CODE
	int percent_complete = 0;
#endif

	instproxy_command_get_name(command, &command_name);

	do {
		/* receive status response */
		instproxy_lock(client);
		res = instproxy_error(property_list_service_receive_plist_with_timeout(client->parent, &node, 1000));
		instproxy_unlock(client);

		/* break out if we have a communication problem */
		if (res != INSTPROXY_E_SUCCESS && res != INSTPROXY_E_RECEIVE_TIMEOUT) {
			debug_info("could not receive plist, error %d", res);
			break;
		}

		/* parse status response */
		if (node) {
			/* check status for possible error to allow reporting it and aborting it gracefully */
			res = instproxy_status_get_error(node, &error_name, &error_description, &error_code);
			if (res != INSTPROXY_E_SUCCESS) {
				debug_info("command: %s, error %d, code 0x%08"PRIx64", name: %s, description: \"%s\"", command_name, res, error_code, error_name, error_description ? error_description: "N/A");
				complete = 1;
			}

			if (error_name) {
				free(error_name);
				error_name = NULL;
			}

			if (error_description) {
				free(error_description);
				error_description = NULL;
			}

			/* check status from response */
			instproxy_status_get_name(node, &status_name);
			if (!status_name) {
				debug_info("ignoring message without Status key:");
				debug_plist(node);
			} else {
				if (!strcmp(status_name, "Complete")) {
					complete = 1;
				} else {
					res = INSTPROXY_E_OP_IN_PROGRESS;
				}
#ifndef STRIP_DEBUG_CODE
				percent_complete = -1;
				instproxy_status_get_percent_complete(node, &percent_complete);
				if (percent_complete >= 0) {
					debug_info("command: %s, status: %s, percent (%d%%)", command_name, status_name, percent_complete);
				} else {
					debug_info("command: %s, status: %s", command_name, status_name);
				}
#endif
				free(status_name);
				status_name = NULL;
			}

			/* invoke status callback function */
			if (status_cb) {
				status_cb(command, node, user_data);
			}

			plist_free(node);
			node = NULL;
		}
	} while (!complete && client->parent);

	if (command_name)
		free(command_name);

	return res;
}

/**
 * Internally used "receive status" thread function that will call the specified
 * callback function when status update messages (or error messages) are
 * received.
 *
 * @param arg Pointer to an allocated struct instproxy_status_data that holds
 *     the required data about the connected client and the callback function.
 *
 * @return Always NULL.
 */
static void* instproxy_receive_status_loop_thread(void* arg)
{
	struct instproxy_status_data *data = (struct instproxy_status_data*)arg;

	/* run until the command is complete or an error occurs */
	(void)instproxy_receive_status_loop(data->client, data->command, data->cbfunc, data->user_data);

	/* cleanup */
	instproxy_lock(data->client);

	debug_info("done, cleaning up.");

	if (data->command) {
		plist_free(data->command);
	}

	if (data->client->receive_status_thread) {
		thread_free(data->client->receive_status_thread);
		data->client->receive_status_thread = THREAD_T_NULL;
	}

	instproxy_unlock(data->client);
	free(data);

	return NULL;
}

/**
 * Internally used helper function that creates a "receive status" thread which
 * will call the passed callback function when a status is received.
 *
 * If async is 0 no thread will be created and the command will run
 * synchronously until it completes or an error occurs.
 *
 * @param client The connected installation proxy client
 * @param command Operation name. Will be passed to the callback function
 *        in async mode or shown in debug messages in sync mode.
 * @param async A boolean indicating if receive loop should be run
 *        asynchronously or block.
 * @param status_cb Pointer to a callback function or NULL.
 * @param user_data Callback data passed to status_cb.
 *
 * @return INSTPROXY_E_SUCCESS when the thread was created (async mode), or
 *         when the command completed successfully (sync).
 *         An INSTPROXY_E_* error value is returned if an error occurred.
 */
static instproxy_error_t instproxy_receive_status_loop_with_callback(instproxy_client_t client, plist_t command, instproxy_command_type_t async, instproxy_status_cb_t status_cb, void *user_data)
{
	if (!client || !client->parent || !command) {
		return INSTPROXY_E_INVALID_ARG;
	}

	if (client->receive_status_thread) {
		return INSTPROXY_E_OP_IN_PROGRESS;
	}

	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;
	if (async == INSTPROXY_COMMAND_TYPE_ASYNC) {
		/* async mode */
		struct instproxy_status_data *data = (struct instproxy_status_data*)malloc(sizeof(struct instproxy_status_data));
		if (data) {
			data->client = client;
			data->command = plist_copy(command);
			data->cbfunc = status_cb;
			data->user_data = user_data;

			if (thread_new(&client->receive_status_thread, instproxy_receive_status_loop_thread, data) == 0) {
				res = INSTPROXY_E_SUCCESS;
			}
		}
	} else {
		/* sync mode as a fallback */
		res = instproxy_receive_status_loop(client, command, status_cb, user_data);
	}

	return res;
}

/**
 * Internal core function to send a command and process the response.
 *
 * @param client The connected installation_proxy client
 * @param command The command specification dictionary.
 * @param async A boolean indicating whether the receive loop should be run
 *        asynchronously or block until completing the command.
 * @param status_cb Callback function to call if a command status is received.
 * @param user_data Callback data passed to status_cb.
 *
 * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if
 *     an error occurred.
 */
static instproxy_error_t instproxy_perform_command(instproxy_client_t client, plist_t command, instproxy_command_type_t async, instproxy_status_cb_t status_cb, void *user_data)
{
	if (!client || !client->parent || !command) {
		return INSTPROXY_E_INVALID_ARG;
	}

	if (client->receive_status_thread) {
		return INSTPROXY_E_OP_IN_PROGRESS;
	}

	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	/* send command */
	instproxy_lock(client);
	res = instproxy_send_command(client, command);
	instproxy_unlock(client);

	/* loop until status or error is received */
	res = instproxy_receive_status_loop_with_callback(client, command, async, status_cb, user_data);

	return res;
}

instproxy_error_t instproxy_browse_with_callback(instproxy_client_t client, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
{
	if (!client || !client->parent || !status_cb)
		return INSTPROXY_E_INVALID_ARG;

	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	plist_t command = plist_new_dict();
	plist_dict_set_item(command, "Command", plist_new_string("Browse"));
	if (client_options)
		plist_dict_set_item(command, "ClientOptions", plist_copy(client_options));

	res = instproxy_perform_command(client, command, INSTPROXY_COMMAND_TYPE_ASYNC, status_cb, (void*)user_data);

	plist_free(command);

	return res;
}

static void instproxy_append_current_list_to_result_cb(plist_t command, plist_t status, void *user_data)
{
	plist_t *result_array = (plist_t*)user_data;
	uint64_t current_amount = 0;
	plist_t current_list = NULL;
	uint64_t i;

	instproxy_status_get_current_list(status, NULL, NULL, &current_amount, &current_list);

	debug_info("current_amount: %d", current_amount);

	if (current_amount > 0) {
		for (i = 0; current_list && (i < current_amount); i++) {
			plist_t item = plist_array_get_item(current_list, i);
			plist_array_append_item(*result_array, plist_copy(item));
		}
	}

	if (current_list)
		plist_free(current_list);
}

instproxy_error_t instproxy_browse(instproxy_client_t client, plist_t client_options, plist_t *result)
{
	if (!client || !client->parent || !result)
		return INSTPROXY_E_INVALID_ARG;

	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	plist_t result_array = plist_new_array();

	plist_t command = plist_new_dict();
	plist_dict_set_item(command, "Command", plist_new_string("Browse"));
	if (client_options)
		plist_dict_set_item(command, "ClientOptions", plist_copy(client_options));

	res = instproxy_perform_command(client, command, INSTPROXY_COMMAND_TYPE_SYNC, instproxy_append_current_list_to_result_cb, (void*)&result_array);

	if (res == INSTPROXY_E_SUCCESS) {
		*result = result_array;
	} else {
		plist_free(result_array);
	}

	plist_free(command);

	return res;
}

static void instproxy_copy_lookup_result_cb(plist_t command, plist_t status, void *user_data)
{
	plist_t* result = (plist_t*)user_data;

	plist_t node = plist_dict_get_item(status, "LookupResult");
	if (node) {
		*result = plist_copy(node);
	}
}

instproxy_error_t instproxy_lookup(instproxy_client_t client, const char** appids, plist_t client_options, plist_t *result)
{
	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;
	int i = 0;
	plist_t lookup_result = NULL;
	plist_t command = NULL;
	plist_t appid_array = NULL;
	plist_t node = NULL;

	if (!client || !client->parent || !result)
		return INSTPROXY_E_INVALID_ARG;

	command = plist_new_dict();
	plist_dict_set_item(command, "Command", plist_new_string("Lookup"));
	if (client_options) {
		node = plist_copy(client_options);
	} else if (appids) {
		node = plist_new_dict();
	}

	/* add bundle identifiers to client options */
	if (appids) {
		appid_array = plist_new_array();
		while (appids[i]) {
			plist_array_append_item(appid_array, plist_new_string(appids[i]));
			i++;
		}
		plist_dict_set_item(node, "BundleIDs", appid_array);
	}

	if (node) {
		plist_dict_set_item(command, "ClientOptions", node);
	}

	res = instproxy_perform_command(client, command, INSTPROXY_COMMAND_TYPE_SYNC, instproxy_copy_lookup_result_cb, (void*)&lookup_result);

	if (res == INSTPROXY_E_SUCCESS) {
		*result = lookup_result;
	} else {
		plist_free(lookup_result);
	}

	plist_free(command);

	return res;
}

instproxy_error_t instproxy_install(instproxy_client_t client, const char *pkg_path, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
{
	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	plist_t command = plist_new_dict();
	plist_dict_set_item(command, "Command", plist_new_string("Install"));
	if (client_options)
		plist_dict_set_item(command, "ClientOptions", plist_copy(client_options));
	plist_dict_set_item(command, "PackagePath", plist_new_string(pkg_path));

	res = instproxy_perform_command(client, command, status_cb == NULL ? INSTPROXY_COMMAND_TYPE_SYNC : INSTPROXY_COMMAND_TYPE_ASYNC, status_cb, user_data);

	plist_free(command);

	return res;
}

instproxy_error_t instproxy_upgrade(instproxy_client_t client, const char *pkg_path, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
{
	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	plist_t command = plist_new_dict();
	plist_dict_set_item(command, "Command", plist_new_string("Upgrade"));
	if (client_options)
		plist_dict_set_item(command, "ClientOptions", plist_copy(client_options));
	plist_dict_set_item(command, "PackagePath", plist_new_string(pkg_path));

	res = instproxy_perform_command(client, command, status_cb == NULL ? INSTPROXY_COMMAND_TYPE_SYNC : INSTPROXY_COMMAND_TYPE_ASYNC, status_cb, user_data);

	plist_free(command);

	return res;
}

instproxy_error_t instproxy_uninstall(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
{
	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	plist_t command = plist_new_dict();
	plist_dict_set_item(command, "Command", plist_new_string("Uninstall"));
	if (client_options)
		plist_dict_set_item(command, "ClientOptions", plist_copy(client_options));
	plist_dict_set_item(command, "ApplicationIdentifier", plist_new_string(appid));

	res = instproxy_perform_command(client, command, status_cb == NULL ? INSTPROXY_COMMAND_TYPE_SYNC : INSTPROXY_COMMAND_TYPE_ASYNC, status_cb, user_data);

	plist_free(command);

	return res;
}

instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist_t client_options, plist_t *result)
{
	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	plist_t command = plist_new_dict();
	plist_dict_set_item(command, "Command", plist_new_string("LookupArchives"));
	if (client_options)
		plist_dict_set_item(command, "ClientOptions", plist_copy(client_options));

	res = instproxy_perform_command(client, command, INSTPROXY_COMMAND_TYPE_SYNC, instproxy_copy_lookup_result_cb, (void*)result);

	plist_free(command);

	return res;
}

instproxy_error_t instproxy_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
{
	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	plist_t command = plist_new_dict();
	plist_dict_set_item(command, "Command", plist_new_string("Archive"));
	if (client_options)
		plist_dict_set_item(command, "ClientOptions", plist_copy(client_options));
	plist_dict_set_item(command, "ApplicationIdentifier", plist_new_string(appid));

	res = instproxy_perform_command(client, command, status_cb == NULL ? INSTPROXY_COMMAND_TYPE_SYNC : INSTPROXY_COMMAND_TYPE_ASYNC, status_cb, user_data);

	plist_free(command);

	return res;
}

instproxy_error_t instproxy_restore(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
{
	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	plist_t command = plist_new_dict();
	plist_dict_set_item(command, "Command", plist_new_string("Restore"));
	if (client_options)
		plist_dict_set_item(command, "ClientOptions", plist_copy(client_options));
	plist_dict_set_item(command, "ApplicationIdentifier", plist_new_string(appid));

	res = instproxy_perform_command(client, command, status_cb == NULL ? INSTPROXY_COMMAND_TYPE_SYNC : INSTPROXY_COMMAND_TYPE_ASYNC, status_cb, user_data);

	plist_free(command);

	return res;
}

instproxy_error_t instproxy_remove_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
{
	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	plist_t command = plist_new_dict();
	plist_dict_set_item(command, "Command", plist_new_string("RemoveArchive"));
	if (client_options)
		plist_dict_set_item(command, "ClientOptions", plist_copy(client_options));
	plist_dict_set_item(command, "ApplicationIdentifier", plist_new_string(appid));

	res = instproxy_perform_command(client, command, status_cb == NULL ? INSTPROXY_COMMAND_TYPE_SYNC : INSTPROXY_COMMAND_TYPE_ASYNC, status_cb, user_data);

	plist_free(command);

	return res;
}

instproxy_error_t instproxy_check_capabilities_match(instproxy_client_t client, const char** capabilities, plist_t client_options, plist_t *result)
{
	if (!client || !capabilities || !result)
		return INSTPROXY_E_INVALID_ARG;

	plist_t lookup_result = NULL;

	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	plist_t command = plist_new_dict();
	plist_dict_set_item(command, "Command", plist_new_string("CheckCapabilitiesMatch"));
	if (client_options)
		plist_dict_set_item(command, "ClientOptions", plist_copy(client_options));

	if (capabilities) {
		int i = 0;
		plist_t capabilities_array = plist_new_array();
		while (capabilities[i]) {
			plist_array_append_item(capabilities_array, plist_new_string(capabilities[i]));
			i++;
		}
		plist_dict_set_item(command, "Capabilities", capabilities_array);
	}

	res = instproxy_perform_command(client, command, INSTPROXY_COMMAND_TYPE_SYNC, instproxy_copy_lookup_result_cb, (void*)&lookup_result);

	if (res == INSTPROXY_E_SUCCESS) {
		*result = lookup_result;
	} else {
		plist_free(lookup_result);
	}

	plist_free(command);

	return res;
}

instproxy_error_t instproxy_status_get_error(plist_t status, char **name, char** description, uint64_t* code)
{
	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	if (!status || !name)
		return INSTPROXY_E_INVALID_ARG;

	plist_t node = plist_dict_get_item(status, "Error");
	if (node) {
		plist_get_string_val(node, name);
	} else {
		/* no error here */
		res = INSTPROXY_E_SUCCESS;
	}

	if (code != NULL) {
		*code = 0;
		node = plist_dict_get_item(status, "ErrorDetail");
		if (node) {
			plist_get_uint_val(node, code);
			*code &= 0xffffffff;
		}
	}

	if (description != NULL) {
		node = plist_dict_get_item(status, "ErrorDescription");
		if (node) {
			plist_get_string_val(node, description);
		}
	}

	if (*name) {
		res = instproxy_strtoerr(*name);
	}

	return res;
}

void instproxy_status_get_name(plist_t status, char **name)
{
	if (name) {
		plist_t node = plist_dict_get_item(status, "Status");
		if (node) {
			plist_get_string_val(node, name);
		} else {
			*name = NULL;
		}
	}
}

void instproxy_status_get_percent_complete(plist_t status, int *percent)
{
	uint64_t val = 0;
	if (percent) {
		plist_t node = plist_dict_get_item(status, "PercentComplete");
		if (node) {
			plist_get_uint_val(node, &val);
			*percent = val;
		}
	}
}

void instproxy_status_get_current_list(plist_t status, uint64_t* total, uint64_t* current_index, uint64_t* current_amount, plist_t* list)
{
	plist_t node = NULL;

	if (status && plist_get_node_type(status) == PLIST_DICT) {
		/* command specific logic: parse browsed list */
		if (list != NULL) {
			node = plist_dict_get_item(status, "CurrentList");
			if (node) {
				*current_amount = plist_array_get_size(node);
				*list = plist_copy(node);
			}
		}

		if (total != NULL) {
			node = plist_dict_get_item(status, "Total");
			if (node) {
				plist_get_uint_val(node, total);
			}
		}

		if (current_amount != NULL) {
			node = plist_dict_get_item(status, "CurrentAmount");
			if (node) {
				plist_get_uint_val(node, current_amount);
			}
		}

		if (current_index != NULL) {
			node = plist_dict_get_item(status, "CurrentIndex");
			if (node) {
				plist_get_uint_val(node, current_index);
			}
		}
	}
}

void instproxy_command_get_name(plist_t command, char** name)
{
	if (name) {
		plist_t node = plist_dict_get_item(command, "Command");
		if (node) {
			plist_get_string_val(node, name);
		} else {
			*name = NULL;
		}
	}
}

plist_t instproxy_client_options_new(void)
{
	return plist_new_dict();
}

void instproxy_client_options_add(plist_t client_options, ...)
{
	if (!client_options)
		return;

	va_list args;
	va_start(args, client_options);
	char *arg = va_arg(args, char*);
	while (arg) {
		char *key = strdup(arg);
		if (!strcmp(key, "SkipUninstall")) {
			int intval = va_arg(args, int);
			plist_dict_set_item(client_options, key, plist_new_bool(intval));
		} else if (!strcmp(key, "ApplicationSINF") || !strcmp(key, "iTunesMetadata") || !strcmp(key, "ReturnAttributes") || !strcmp(key, "BundleIDs")) {
			plist_t plistval = va_arg(args, plist_t);
			if (!plistval) {
				free(key);
				break;
			}
			plist_dict_set_item(client_options, key, plist_copy(plistval));
		} else {
			char *strval = va_arg(args, char*);
			if (!strval) {
				free(key);
				break;
			}
			plist_dict_set_item(client_options, key, plist_new_string(strval));
		}
		free(key);
		arg = va_arg(args, char*);
	}
	va_end(args);
}

void instproxy_client_options_set_return_attributes(plist_t client_options, ...)
{
	if (!client_options)
		return;

	plist_t return_attributes = plist_new_array();

	va_list args;
	va_start(args, client_options);
	char *arg = va_arg(args, char*);
	while (arg) {
		char *attribute = strdup(arg);
		plist_array_append_item(return_attributes, plist_new_string(attribute));
		free(attribute);
		arg = va_arg(args, char*);
	}
	va_end(args);

	plist_dict_set_item(client_options, "ReturnAttributes", return_attributes);
}

void instproxy_client_options_free(plist_t client_options)
{
	if (client_options) {
		plist_free(client_options);
	}
}

instproxy_error_t instproxy_client_get_path_for_bundle_identifier(instproxy_client_t client, const char* bundle_id, char** path)
{
	if (!client || !client->parent || !bundle_id)
		return INSTPROXY_E_INVALID_ARG;

	plist_t apps = NULL;

	// create client options for any application types
	plist_t client_opts = instproxy_client_options_new();
	instproxy_client_options_add(client_opts, "ApplicationType", "Any", NULL);

	// only return attributes we need
	instproxy_client_options_set_return_attributes(client_opts, "CFBundleIdentifier", "CFBundleExecutable", "Path", NULL);

	// only query for specific appid
	const char* appids[] = {bundle_id, NULL};

	// query device for list of apps
	instproxy_error_t ierr = instproxy_lookup(client, appids, client_opts, &apps);

	instproxy_client_options_free(client_opts);

	if (ierr != INSTPROXY_E_SUCCESS) {
		return ierr;
	}

	plist_t app_found = plist_access_path(apps, 1, bundle_id);
	if (!app_found) {
		if (apps)
			plist_free(apps);
		*path = NULL;
		return INSTPROXY_E_OP_FAILED;
	}

	char* path_str = NULL;
	plist_t path_p = plist_dict_get_item(app_found, "Path");
	if (path_p) {
		plist_get_string_val(path_p, &path_str);
	}

	char* exec_str = NULL;
	plist_t exec_p = plist_dict_get_item(app_found, "CFBundleExecutable");
	if (exec_p) {
		plist_get_string_val(exec_p, &exec_str);
	}

	if (!path_str) {
		debug_info("app path not found");
		return INSTPROXY_E_OP_FAILED;
	}

	if (!exec_str) {
		debug_info("bundle executable not found");
		return INSTPROXY_E_OP_FAILED;
	}

	plist_free(apps);

	char* ret = (char*)malloc(strlen(path_str) + 1 + strlen(exec_str) + 1);
	strcpy(ret, path_str);
	strcat(ret, "/");
	strcat(ret, exec_str);

	*path = ret;

	if (path_str) {
		free(path_str);
	}

	if (exec_str) {
		free(exec_str);
	}

	return INSTPROXY_E_SUCCESS;
}
