/*
 * idevicedevmodectl.c
 * List or enable Developer Mode on iOS 16+ devices
 *
 * Copyright (c) 2022 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

#define TOOL_NAME "idevicedevmodectl"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <sys/stat.h>
#include <errno.h>
#ifndef WIN32
#include <signal.h>
#endif

#ifdef WIN32
#include <windows.h>
#define __usleep(x) Sleep(x/1000)
#else
#include <arpa/inet.h>
#define __usleep(x) usleep(x)
#endif

#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/lockdown.h>
#include <libimobiledevice/property_list_service.h>
#include <libimobiledevice-glue/utils.h>

#define AMFI_LOCKDOWN_SERVICE_NAME "com.apple.amfi.lockdown"

static char* udid = NULL;
static int use_network = 0;

static void print_usage(int argc, char **argv, int is_error)
{
	char *name = strrchr(argv[0], '/');
	fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0]));
	fprintf(is_error ? stderr : stdout,
		"\n"
		"Enable Developer Mode on iOS 16+ devices or print the current status.\n"
		"\n"
		"Where COMMAND is one of:\n"
		"  list          Print the Developer Mode status of all connected devices\n"
                "                or for a specific one if --udid is given.\n"
		"  enable        Enable Developer Mode (device will reboot),\n"
		"                and confirm it after device booted up again.\n"
		"\n"
		"  arm           Arm the Developer Mode (device will reboot)\n"
		"  confirm       Confirm enabling of Developer Mode\n"
		"  reveal        Reveal the Developer Mode menu on the device\n"
		"\n"
		"The following OPTIONS are accepted:\n"
		"  -u, --udid UDID       target specific device by UDID\n"
		"  -n, --network         connect to network device\n"
		"  -d, --debug           enable communication debugging\n"
		"  -h, --help            print usage information\n"
		"  -v, --version         print version information\n"
		"\n"
		"Homepage:    <" PACKAGE_URL ">\n"
		"Bug Reports: <" PACKAGE_BUGREPORT ">\n"
	);
}

enum {
	OP_LIST,
	OP_ENABLE,
	OP_ARM,
	OP_CONFIRM,
	OP_REVEAL,
	NUM_OPS
};
#define DEV_MODE_REVEAL   0
#define DEV_MODE_ARM      1
#define DEV_MODE_ENABLE   2

static int get_developer_mode_status(const char* device_udid, int _use_network)
{
	idevice_error_t ret;
	idevice_t device = NULL;
	lockdownd_client_t lockdown = NULL;
	lockdownd_error_t lerr = LOCKDOWN_E_UNKNOWN_ERROR;
	plist_t val = NULL;

	ret = idevice_new_with_options(&device, device_udid, (_use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX);
	if (ret != IDEVICE_E_SUCCESS) {
		return -1;
	}

	if (LOCKDOWN_E_SUCCESS != (lerr = lockdownd_client_new_with_handshake(device, &lockdown, TOOL_NAME))) {
		idevice_free(device);
		return -1;
	}

	lerr = lockdownd_get_value(lockdown, "com.apple.security.mac.amfi", "DeveloperModeStatus", &val);
	if (lerr != LOCKDOWN_E_SUCCESS) {
		fprintf(stderr, "ERROR: Could not get DeveloperModeStatus: %s\nPlease note that this feature is only available on iOS 16+.\n", lockdownd_strerror(lerr));
		lockdownd_client_free(lockdown);
		idevice_free(device);
		return -2;
	}

	uint8_t dev_mode_status = 0;
	plist_get_bool_val(val, &dev_mode_status);
	plist_free(val);

	lockdownd_client_free(lockdown);
	idevice_free(device);

	return dev_mode_status;
}

static int amfi_service_send_msg(property_list_service_client_t amfi, plist_t msg)
{
	int res;
	property_list_service_error_t perr;

	perr = property_list_service_send_xml_plist(amfi, plist_copy(msg));
	if (perr != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		fprintf(stderr, "Could not send request to device: %d\n", perr);
		res = 2;
	} else {
		plist_t reply = NULL;
		perr = property_list_service_receive_plist(amfi, &reply);
		if (perr == PROPERTY_LIST_SERVICE_E_SUCCESS) {
			uint8_t success = 0;
			plist_t val = plist_dict_get_item(reply, "Error");
			if (val) {
				const char* err = plist_get_string_ptr(val, NULL);
				fprintf(stderr, "Request failed: %s\n", err);
				if (strstr(err, "passcode")) {
					res = 2;
				} else {
					res = 1;
				}
			} else {
				val = plist_dict_get_item(reply, "success");
				if (val) {
					plist_get_bool_val(val, &success);
				}
				if (success) {
					res = 0;
				} else {
					res = 1;
				}
			}
		} else {
			fprintf(stderr, "Could not receive reply from device: %d\n", perr);
			res = 2;
		}
		plist_free(reply);
	}
	return res;
}

static int amfi_send_action(idevice_t device, unsigned int action)
{
	lockdownd_client_t lockdown = NULL;
	lockdownd_service_descriptor_t service = NULL;
	lockdownd_error_t lerr;

	if (LOCKDOWN_E_SUCCESS != (lerr = lockdownd_client_new_with_handshake(device, &lockdown, TOOL_NAME))) {
		fprintf(stderr, "ERROR: Could not connect to lockdownd, error code %d\n", lerr);
		return 1;
	}

	lerr = lockdownd_start_service(lockdown, AMFI_LOCKDOWN_SERVICE_NAME, &service);
	if (lerr != LOCKDOWN_E_SUCCESS) {
		fprintf(stderr, "Could not start service %s: %s\nPlease note that this feature is only available on iOS 16+.\n", AMFI_LOCKDOWN_SERVICE_NAME, lockdownd_strerror(lerr));
		lockdownd_client_free(lockdown);
		return 1;
	}
	lockdownd_client_free(lockdown);
	lockdown = NULL;

	property_list_service_client_t amfi = NULL;
	if (property_list_service_client_new(device, service, &amfi) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		fprintf(stderr, "Could not connect to %s on device\n", AMFI_LOCKDOWN_SERVICE_NAME);
		if (service)
			lockdownd_service_descriptor_free(service);
		idevice_free(device);
		return 1;
	}
	lockdownd_service_descriptor_free(service);

	plist_t dict = plist_new_dict();
	plist_dict_set_item(dict, "action", plist_new_uint(action));

	int result = amfi_service_send_msg(amfi, dict);
	plist_free(dict);

	property_list_service_client_free(amfi);
	amfi = NULL;

	return result;
}

static int device_connected = 0;

static void device_event_cb(const idevice_event_t* event, void* userdata)
{
	if (use_network && event->conn_type != CONNECTION_NETWORK) {
		return;
	}
	if (!use_network && event->conn_type != CONNECTION_USBMUXD) {
		return;
	}
	if (event->event == IDEVICE_DEVICE_ADD) {
		if (!udid) {
			udid = strdup(event->udid);
		}
		if (strcmp(udid, event->udid) == 0) {
			device_connected = 1;
		}
	} else if (event->event == IDEVICE_DEVICE_REMOVE) {
		if (strcmp(udid, event->udid) == 0) {
			device_connected = 0;
		}
	}
}


#define WAIT_INTERVAL 200000
#define WAIT_MAX(x) (x * (1000000 / WAIT_INTERVAL))
#define WAIT_FOR(cond, timeout) { int __repeat = WAIT_MAX(timeout); while (!(cond) && __repeat-- > 0) { __usleep(WAIT_INTERVAL); } }

int main(int argc, char *argv[])
{
	idevice_t device = NULL;
	idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
	lockdownd_client_t lockdown = NULL;
	lockdownd_error_t lerr = LOCKDOWN_E_UNKNOWN_ERROR;
	int res = 0;
	int i;
	int op = -1;
	plist_t val = NULL;

	int c = 0;
	const struct option longopts[] = {
		{ "debug", no_argument, NULL, 'd' },
		{ "help", no_argument, NULL, 'h' },
		{ "udid", required_argument, NULL, 'u' },
		{ "network", no_argument, NULL, 'n' },
		{ "version", no_argument, NULL, 'v' },
		{ NULL, 0, NULL, 0}
	};

#ifndef WIN32
	signal(SIGPIPE, SIG_IGN);
#endif
	/* parse cmdline args */
	while ((c = getopt_long(argc, argv, "dhu:nv", longopts, NULL)) != -1) {
		switch (c) {
		case 'd':
			idevice_set_debug_level(1);
			break;
		case 'u':
			if (!*optarg) {
				fprintf(stderr, "ERROR: UDID argument must not be empty!\n");
				print_usage(argc, argv, 1);
				return 2;
			}
			udid = optarg;
			break;
		case 'n':
			use_network = 1;
			break;
		case 'h':
			print_usage(argc, argv, 0);
			return 0;
		case 'v':
			printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
			return 0;
		default:
			print_usage(argc, argv, 1);
			return 2;
		}
	}
	argc -= optind;
	argv += optind;

	if (!argv[0]) {
		fprintf(stderr, "ERROR: Missing command.\n");
		print_usage(argc+optind, argv-optind, 1);
		return 2;
	}

	i = 0;
	if (!strcmp(argv[i], "list")) {
		op = OP_LIST;
	}
	else if (!strcmp(argv[i], "enable")) {
		op = OP_ENABLE;
	}
	else if (!strcmp(argv[i], "arm")) {
		op = OP_ARM;
	}
	else if (!strcmp(argv[i], "confirm")) {
		op = OP_CONFIRM;
	}
	else if (!strcmp(argv[i], "reveal")) {
		op = OP_REVEAL;
	}

	if ((op == -1) || (op >= NUM_OPS)) {
		fprintf(stderr, "ERROR: Unsupported command '%s'\n", argv[i]);
		print_usage(argc+optind, argv-optind, 1);
		return 2;
	}

	if (op == OP_LIST) {
		idevice_info_t *dev_list = NULL;

		if (idevice_get_device_list_extended(&dev_list, &i) < 0) {
			fprintf(stderr, "ERROR: Unable to retrieve device list!\n");
			return -1;
		}
		if (i > 0) {
			printf("%-40s    %s\n", "Device", "DeveloperMode");
		}
		for (i = 0; dev_list[i] != NULL; i++) {
			if (dev_list[i]->conn_type == CONNECTION_USBMUXD && use_network) continue;
			if (dev_list[i]->conn_type == CONNECTION_NETWORK && !use_network) continue;
			if (udid && (strcmp(dev_list[i]->udid, udid) != 0)) continue;
			int mode = get_developer_mode_status(dev_list[i]->udid, use_network);
			const char *mode_str = "N/A";
			if (mode == 1) {
				mode_str = "enabled";
			} else if (mode == 0) {
				mode_str = "disabled";
			}
			printf("%-40s    %s\n", dev_list[i]->udid, mode_str);
		}
		idevice_device_list_extended_free(dev_list);

		return 0;
	}

	idevice_subscription_context_t context = NULL;
	idevice_events_subscribe(&context, device_event_cb, NULL);

	WAIT_FOR(device_connected, 10);

	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");
		}
		return 1;
	}

	if (!udid) {
		idevice_get_udid(device, &udid);
	}

	if (LOCKDOWN_E_SUCCESS != (lerr = lockdownd_client_new_with_handshake(device, &lockdown, TOOL_NAME))) {
		fprintf(stderr, "ERROR: Could not connect to lockdownd, error code %d\n", lerr);
		idevice_free(device);
		return 1;
	}

	lerr = lockdownd_get_value(lockdown, "com.apple.security.mac.amfi", "DeveloperModeStatus", &val);
	lockdownd_client_free(lockdown);
	lockdown = NULL;
	if (lerr != LOCKDOWN_E_SUCCESS) {
		fprintf(stderr, "ERROR: Could not get DeveloperModeStatus: %s\nPlease note that this feature is only available on iOS 16+.\n", lockdownd_strerror(lerr));
		idevice_free(device);
		return 1;
	}

	uint8_t dev_mode_status = 0;
	plist_get_bool_val(val, &dev_mode_status);

	if ((op == OP_ENABLE || op == OP_ARM) && dev_mode_status) {
		if (dev_mode_status) {
			printf("DeveloperMode is already enabled.\n");
			return 0;
		}
		res = 0;
	} else {	
		if (op == OP_ENABLE || op == OP_ARM) {
			res = amfi_send_action(device, DEV_MODE_ARM);
			if (res == 0) {
				if (op == OP_ARM) {
					printf("%s: Developer Mode armed, device will reboot now.\n", udid);
				} else {
					printf("%s: Developer Mode armed, waiting for reboot...\n", udid);

					// waiting for device to disconnect...
					WAIT_FOR(!device_connected, 20);

					// waiting for device to reconnect...
					WAIT_FOR(device_connected, 60);

					res = amfi_send_action(device, DEV_MODE_ENABLE);
					if (res == 0) {
						printf("%s: Developer Mode successfully enabled.\n", udid);
					} else {
						printf("%s: Failed to enable developer mode (%d)\n", udid, res);
					}
				}
			} else if (res == 2) {
				amfi_send_action(device, DEV_MODE_REVEAL);
				printf("%s: Developer Mode could not be enabled because the device has a passcode set. You have to enable it on the device itself under Settings -> Privacy & Security -> Developer Mode.\n", udid);
			} else {
				printf("%s: Failed to arm Developer Mode (%d)\n", udid, res);
			}
		} else if (op == OP_CONFIRM) {
			res = amfi_send_action(device, DEV_MODE_ENABLE);
			if (res == 0) {
				printf("%s: Developer Mode successfully enabled.\n", udid);
			} else {
				printf("%s: Failed to enable Developer Mode (%d)\n", udid, res);
			}
		} else if (op == OP_REVEAL) {
			res = amfi_send_action(device, DEV_MODE_REVEAL);
			if (res == 0) {
				printf("%s: Developer Mode menu revealed successfully.\n", udid);
			} else {
				printf("%s: Failed to reveal Developer Mode menu (%d)\n", udid, res);
			}
		}
	}

	idevice_free(device);

	return res;
}
