/*
 * idevicedebug.c
 * Interact with the debugserver service of a device.
 *
 * Copyright (c) 2014-2015 Martin Szulecki 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

#define TOOL_NAME "idevicedebug"

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <libgen.h>

#ifdef WIN32
#include <windows.h>
#define sleep(x) Sleep(x*1000)
#endif

#include <libimobiledevice/installation_proxy.h>
#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/debugserver.h>
#include <plist/plist.h>
#include "common/debug.h"

static int debug_level = 0;

#define log_debug(...) if (debug_level > 0) { printf(__VA_ARGS__); fputc('\n', stdout); }

enum cmd_mode {
	CMD_NONE = 0,
	CMD_RUN
};

static int quit_flag = 0;

static void on_signal(int sig)
{
	fprintf(stderr, "Exiting...\n");
	quit_flag++;
}

static void cancel_receive()
{
	return quit_flag;
}

static instproxy_error_t instproxy_client_get_object_by_key_from_info_dictionary_for_bundle_identifier(instproxy_client_t client, const char* appid, const char* key, plist_t* node)
{
	if (!client || !appid || !key)
		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", key, NULL);

	// only query for specific appid
	const char* appids[] = {appid, 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, appid);
	if (!app_found) {
		if (apps)
			plist_free(apps);
		*node = NULL;
		return INSTPROXY_E_OP_FAILED;
	}

	plist_t object = plist_dict_get_item(app_found, key);
	if (object) {
		*node = plist_copy(object);
	} else {
		log_debug("key %s not found", key);
		return INSTPROXY_E_OP_FAILED;
	}

	plist_free(apps);

	return INSTPROXY_E_SUCCESS;
}

static debugserver_error_t debugserver_client_handle_response(debugserver_client_t client, char** response, int* exit_status)
{
	debugserver_error_t dres = DEBUGSERVER_E_SUCCESS;
	char* o = NULL;
	char* r = *response;

        /* Documentation of response codes can be found here:
           https://github.com/llvm/llvm-project/blob/4fe839ef3a51e0ea2e72ea2f8e209790489407a2/lldb/docs/lldb-gdb-remote.txt#L1269 */
        
	if (r[0] == 'O') {
		/* stdout/stderr */
		debugserver_decode_string(r + 1, strlen(r) - 1, &o);
		printf("%s", o);
		fflush(stdout);
	} else if (r[0] == 'T') {
		/* thread stopped information */
		log_debug("Thread stopped. Details:\n%s", r + 1);
                /* "Thread stopped" seems to happen when assert() fails. Use bash convention where signals cause an exit status of 128 + signal */
                *exit_status = 128 + SIGABRT;
                /* Break out of the loop. */
		dres = DEBUGSERVER_E_UNKNOWN_ERROR;
	} else if (r[0] == 'E') {
		printf("ERROR: %s\n", r + 1);
	} else if (r[0] == 'W' || r[0] == 'X') {
		/* process exited */
		debugserver_decode_string(r + 1, strlen(r) - 1, &o);
		if (o != NULL) {
			printf("Exit %s: %u\n", (r[0] == 'W' ? "status" : "due to signal"), o[0]);
			/* Use bash convention where signals cause an exit status of 128 + signal */
			*exit_status = o[0] + (r[0] == 'W' ? 0 : 128);
		} else {
                  debug_info("Unable to decode exit status from %s", r);
                  dres = DEBUGSERVER_E_UNKNOWN_ERROR;
                }
	} else if (r && strlen(r) == 0) {
		log_debug("empty response");
	} else {
		log_debug("ERROR: unhandled response '%s'", r);
	}

        if (o != NULL) {
          free(o);
          o = NULL;
        }

        free(*response);
        *response = NULL;
	return dres;
}

static void print_usage(int argc, char **argv)
{
	char *name = NULL;
	name = strrchr(argv[0], '/');
	printf("Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0]));
	printf("\n");
	printf("Interact with the debugserver service of a device.\n");
	printf("\n");
	printf("Where COMMAND is one of:\n");
	printf("  run BUNDLEID [ARGS...]\trun app with BUNDLEID and optional ARGS on device.\n");
	printf("\n");
	printf("The following OPTIONS are accepted:\n");
	printf("  -u, --udid UDID\ttarget specific device by UDID\n");
	printf("  -n, --network\t\tconnect to network device\n");
	printf("      --detach\t\tdetach from app after launch, keeping it running\n");
	printf("  -e, --env NAME=VALUE\tset environment variable NAME to VALUE\n");
	printf("  -d, --debug\t\tenable communication debugging\n");
	printf("  -h, --help\t\tprints usage information\n");
	printf("  -v, --version\t\tprints version information\n");
	printf("\n");
	printf("Homepage:    <" PACKAGE_URL ">\n");
	printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n");
}

int main(int argc, char *argv[])
{
	int res = -1;
	idevice_t device = NULL;
	idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
	instproxy_client_t instproxy_client = NULL;
	debugserver_client_t debugserver_client = NULL;
	int i;
	int cmd = CMD_NONE;
	const char* udid = NULL;
	int use_network = 0;
	int detach_after_start = 0;
	const char* bundle_identifier = NULL;
	char* path = NULL;
	char* working_directory = NULL;
	char **newlist = NULL;
	char** environment = NULL;
	int environment_index = 0;
	int environment_count = 0;
	char* response = NULL;
	debugserver_command_t command = NULL;
	debugserver_error_t dres = DEBUGSERVER_E_UNKNOWN_ERROR;

	/* map signals */
	signal(SIGINT, on_signal);
	signal(SIGTERM, on_signal);
#ifndef WIN32
	signal(SIGQUIT, on_signal);
	signal(SIGPIPE, SIG_IGN);
#endif

	/* parse command line arguments */
	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
			debug_level++;
			idevice_set_debug_level(debug_level);
			continue;
		} else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) {
			i++;
			if (!argv[i] || !*argv[i]) {
				print_usage(argc, argv);
				res = 0;
				goto cleanup;
			}
			udid = argv[i];
			continue;
		} else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--network")) {
			use_network = 1;
			continue;
		} else if (!strcmp(argv[i], "--detach")) {
			detach_after_start = 1;
			continue;
		} else if (!strcmp(argv[i], "-e") || !strcmp(argv[i], "--env")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) <= 1) || strchr(argv[i], '=') == NULL) {
				print_usage(argc, argv);
				res = 0;
				goto cleanup;
			}
			/* add environment variable */
			if (!newlist)
				newlist = malloc((environment_count + 1) * sizeof(char*));
			else
				newlist = realloc(environment, (environment_count + 1) * sizeof(char*));
			newlist[environment_count++] = strdup(argv[i]);
			environment = newlist;
			continue;
		} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
			print_usage(argc, argv);
			res = 0;
			goto cleanup;
		} else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
			printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
			res = 0;
			goto cleanup;
		} else if (!strcmp(argv[i], "run")) {
			cmd = CMD_RUN;

			i++;
			if (!argv[i]) {
				/* make sure at least the bundle identifier was provided */
				printf("Please supply the bundle identifier of the app to run.\n");
				print_usage(argc, argv);
				res = 0;
				goto cleanup;
			}
			/*  read bundle identifier */
			bundle_identifier = argv[i];
			break;
		} else {
			print_usage(argc, argv);
			res = 0;
			goto cleanup;
		}
	}

	if (environment) {
		newlist = realloc(environment, (environment_count + 1) * sizeof(char*));
		newlist[environment_count] = NULL;
		environment = newlist;
	}

	/* verify options */
	if (cmd == CMD_NONE) {
		print_usage(argc, argv);
		goto cleanup;
	}

	/* connect to the device */
	ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX);
	if (ret != IDEVICE_E_SUCCESS) {
		if (udid) {
			printf("No device found with udid %s.\n", udid);
		} else {
			printf("No device found.\n");
		}
		goto cleanup;
	}

	switch (cmd) {
		case CMD_RUN:
		default:
			/* get the path to the app and it's working directory */
			if (instproxy_client_start_service(device, &instproxy_client, TOOL_NAME) != INSTPROXY_E_SUCCESS) {
				fprintf(stderr, "Could not start installation proxy service.\n");
				goto cleanup;
			}

			instproxy_client_get_path_for_bundle_identifier(instproxy_client, bundle_identifier, &path);
			if (!path) {
				fprintf(stderr, "Invalid bundle identifier: %s\n", bundle_identifier);
				goto cleanup;
			}

			plist_t container = NULL;
			instproxy_client_get_object_by_key_from_info_dictionary_for_bundle_identifier(instproxy_client, bundle_identifier, "Container", &container);
			instproxy_client_free(instproxy_client);
			instproxy_client = NULL;

			if (container && (plist_get_node_type(container) == PLIST_STRING)) {
				plist_get_string_val(container, &working_directory);
				log_debug("working_directory: %s\n", working_directory);
				plist_free(container);
			} else {
				plist_free(container);
				fprintf(stderr, "Could not determine container path for bundle identifier %s.\n", bundle_identifier);
				goto cleanup;
			}

			/* start and connect to debugserver */
			if (debugserver_client_start_service(device, &debugserver_client, TOOL_NAME) != DEBUGSERVER_E_SUCCESS) {
				fprintf(stderr,
					"Could not start com.apple.debugserver!\n"
					"Please make sure to mount the developer disk image first:\n"
					"  1) Get the iOS version from `ideviceinfo -k ProductVersion`.\n"
					"  2) Find the matching iPhoneOS DeveloperDiskImage.dmg files.\n"
					"  3) Run `ideviceimagemounter` with the above path.\n");
				goto cleanup;
			}

                        /* set receive params */
                        if (debugserver_client_set_receive_params(debugserver_client, cancel_receive, 250) != DEBUGSERVER_E_SUCCESS) {
				fprintf(stderr, "Error in debugserver_client_set_receive_params\n");
				goto cleanup;
			}

			/* enable logging for the session in debug mode */
			if (debug_level) {
				log_debug("Setting logging bitmask...");
				debugserver_command_new("QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE|LOG_RNB_PACKETS;", 0, NULL, &command);
				dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
				debugserver_command_free(command);
				command = NULL;
				if (response) {
					if (strncmp(response, "OK", 2)) {
						debugserver_client_handle_response(debugserver_client, &response, NULL);
						goto cleanup;
					}
					free(response);
					response = NULL;
				}
			}

			/* set maximum packet size */
			log_debug("Setting maximum packet size...");
			char* packet_size[2] = {strdup("1024"), NULL};
			debugserver_command_new("QSetMaxPacketSize:", 1, packet_size, &command);
			free(packet_size[0]);
			dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
			debugserver_command_free(command);
			command = NULL;
			if (response) {
				if (strncmp(response, "OK", 2)) {
					debugserver_client_handle_response(debugserver_client, &response, NULL);
					goto cleanup;
				}
				free(response);
				response = NULL;
			}

			/* set working directory */
			log_debug("Setting working directory...");
			char* working_dir[2] = {working_directory, NULL};
			debugserver_command_new("QSetWorkingDir:", 1, working_dir, &command);
			dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
			debugserver_command_free(command);
			command = NULL;
			if (response) {
				if (strncmp(response, "OK", 2)) {
					debugserver_client_handle_response(debugserver_client, &response, NULL);
					goto cleanup;
				}
				free(response);
				response = NULL;
			}

			/* set environment */
			if (environment) {
				log_debug("Setting environment...");
				for (environment_index = 0; environment_index < environment_count; environment_index++) {
					log_debug("setting environment variable: %s", environment[environment_index]);
					debugserver_client_set_environment_hex_encoded(debugserver_client, environment[environment_index], NULL);
				}
			}

			/* set arguments and run app */
			log_debug("Setting argv...");
			i++; /* i is the offset of the bundle identifier, thus skip it */
			int app_argc = (argc - i + 2);
			char **app_argv = (char**)malloc(sizeof(char*) * app_argc);
			app_argv[0] = path;
			log_debug("app_argv[%d] = %s", 0, app_argv[0]);
			app_argc = 1;
			while (i < argc && argv && argv[i]) {
				log_debug("app_argv[%d] = %s", app_argc, argv[i]);
				app_argv[app_argc++] = argv[i];
				i++;
			}
			app_argv[app_argc] = NULL;
			debugserver_client_set_argv(debugserver_client, app_argc, app_argv, NULL);
			free(app_argv);

			/* check if launch succeeded */
			log_debug("Checking if launch succeeded...");
			debugserver_command_new("qLaunchSuccess", 0, NULL, &command);
			dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
			debugserver_command_free(command);
			command = NULL;
			if (response) {
				if (strncmp(response, "OK", 2)) {
					debugserver_client_handle_response(debugserver_client, &response, NULL);
					goto cleanup;
				}
				free(response);
				response = NULL;
			}

			if (detach_after_start) {
				log_debug("Detaching from app");
				debugserver_command_new("D", 0, NULL, &command);
				dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
				debugserver_command_free(command);
				command = NULL;

				res = (dres == DEBUGSERVER_E_SUCCESS) ? 0: -1;
				break;
			}

			/* set thread */
			log_debug("Setting thread...");
			debugserver_command_new("Hc0", 0, NULL, &command);
			dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
			debugserver_command_free(command);
			command = NULL;
			if (response) {
				if (strncmp(response, "OK", 2)) {
					debugserver_client_handle_response(debugserver_client, &response, NULL);
					goto cleanup;
				}
				free(response);
				response = NULL;
			}

			/* continue running process */
			log_debug("Continue running process...");
			debugserver_command_new("c", 0, NULL, &command);
			dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
			debugserver_command_free(command);
			command = NULL;

			/* main loop which is parsing/handling packets during the run */
			log_debug("Entering run loop...");
			while (!quit_flag) {
				if (dres != DEBUGSERVER_E_SUCCESS) {
					log_debug("failed to receive response; error %d", dres);
					break;
				}

				if (response) {
					log_debug("response: %s", response);
					if (strncmp(response, "OK", 2)) {
						dres = debugserver_client_handle_response(debugserver_client, &response, &res);
						if (dres != DEBUGSERVER_E_SUCCESS) {
							debug_info("failed to process response; error %d; %s", dres, response);
							break;
						}
					}
				}
				if (res >= 0) {
					goto cleanup;
				}

				dres = debugserver_client_receive_response(debugserver_client, &response, NULL);
			}

			/* kill process after we finished */
			log_debug("Killing process...");
			debugserver_command_new("k", 0, NULL, &command);
			dres = debugserver_client_send_command(debugserver_client, command, &response, NULL);
			debugserver_command_free(command);
			command = NULL;
			if (response) {
				if (strncmp(response, "OK", 2)) {
					debugserver_client_handle_response(debugserver_client, &response, NULL);
					goto cleanup;
				}
				free(response);
				response = NULL;
			}

                        if (res < 0) {
                          res = (dres == DEBUGSERVER_E_SUCCESS) ? 0: -1;
                        }
		break;
	}

cleanup:
	/* cleanup the house */
	if (environment) {
		for (environment_index = 0; environment_index < environment_count; environment_index++) {
			free(environment[environment_index]);
		}
		free(environment);
	}

	if (working_directory)
		free(working_directory);

	if (path)
		free(path);

	if (response)
		free(response);

	if (debugserver_client)
		debugserver_client_free(debugserver_client);

	if (device)
		idevice_free(device);

	return res;
}
