/*
 * idevicesetlocation.c
 * Simulate location on iOS device with mounted developer disk image
 *
 * Copyright (c) 2016-2020 Nikias Bassen, All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; 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 "idevicesetlocation"

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>

#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/lockdown.h>
#include <libimobiledevice/service.h>

#include <endianness.h>

#define DT_SIMULATELOCATION_SERVICE "com.apple.dt.simulatelocation"

enum {
	SET_LOCATION = 0,
	RESET_LOCATION = 1
};

static void print_usage(int argc, char **argv, int is_error)
{
	char *bname = strrchr(argv[0], '/');
	bname = (bname) ? bname + 1 : argv[0];

	fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] -- <LAT> <LONG>\n", bname);
	fprintf(is_error ? stderr : stdout, "       %s [OPTIONS] reset\n", bname);
	fprintf(is_error ? stderr : stdout,
		"\n"
		"OPTIONS:\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            prints usage information\n"
		"  -v, --version         prints version information\n"
		"\n"
		"Homepage:    <" PACKAGE_URL ">\n"
		"Bug Reports: <" PACKAGE_BUGREPORT ">\n"
	);
}

int main(int argc, char **argv)
{
	int c = 0;
	const struct option longopts[] = {
		{ "help",    no_argument,       NULL, 'h' },
		{ "udid",    required_argument, NULL, 'u' },
		{ "debug",   no_argument,       NULL, 'd' },
		{ "network", no_argument,       NULL, 'n' },
		{ "version", no_argument,       NULL, 'v' },
		{ NULL, 0, NULL, 0}
	};
	uint32_t mode = 0;
	const char *udid = NULL;
	int use_network = 0;

	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 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 ((argc > 2) || (argc < 1)) {
		print_usage(argc+optind, argv-optind, 1);
		return 1;
	}

	if (argc == 2) {
		mode = SET_LOCATION;
	} else if (argc == 1) {
		if (strcmp(argv[0], "reset") == 0) {
			mode = RESET_LOCATION;
		} else {
			print_usage(argc+optind, argv-optind, 1);
			return 1;
		}
	}

	idevice_t device = NULL;

	if (idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX) != IDEVICE_E_SUCCESS) {
		if (udid) {
			printf("ERROR: Device %s not found!\n", udid);
		} else {
			printf("ERROR: No device found!\n");
		}
		return 1;
	}

	lockdownd_client_t lockdown = NULL;
	lockdownd_error_t lerr = lockdownd_client_new_with_handshake(device, &lockdown, TOOL_NAME);
	if (lerr != LOCKDOWN_E_SUCCESS) {
		idevice_free(device);
		printf("ERROR: Could not connect to lockdownd: %s (%d)\n", lockdownd_strerror(lerr), lerr);
		return 1;
	}

	lockdownd_service_descriptor_t svc = NULL;
	lerr = lockdownd_start_service(lockdown, DT_SIMULATELOCATION_SERVICE, &svc);
	if (lerr != LOCKDOWN_E_SUCCESS) {
		unsigned int device_version = idevice_get_device_version(device);
		lockdownd_client_free(lockdown);
		idevice_free(device);
		printf("ERROR: Could not start the simulatelocation service: %s\n", lockdownd_strerror(lerr));
		if (device_version >= IDEVICE_DEVICE_VERSION(17,0,0)) {
			printf("Note: This tool is currently not supported on iOS 17+\n");
		} else {
			printf("Make sure a developer disk image is mounted!\n");
		}
		return 1;
	}
	lockdownd_client_free(lockdown);

	service_client_t service = NULL;

	service_error_t serr = service_client_new(device, svc, &service);

	lockdownd_service_descriptor_free(svc);

	if (serr != SERVICE_E_SUCCESS) {
		idevice_free(device);
		printf("ERROR: Could not connect to simulatelocation service (%d)\n", serr);
		return 1;
	}

	uint32_t l;
	uint32_t s = 0;

	l = htobe32(mode);
	service_send(service, (const char*)&l, 4, &s);
	if (mode == SET_LOCATION) {
		int len = 4 + strlen(argv[0]) + 4 + strlen(argv[1]);
		char *buf = malloc(len);
		uint32_t latlen;
		latlen = strlen(argv[0]);
		l = htobe32(latlen);
		memcpy(buf, &l, 4);
		memcpy(buf+4, argv[0], latlen);
		uint32_t longlen = strlen(argv[1]);
		l = htobe32(longlen);
		memcpy(buf+4+latlen, &l, 4);
		memcpy(buf+4+latlen+4, argv[1], longlen);

		s = 0;
		service_send(service, buf, len, &s);
	}

	idevice_free(device);

	return 0;
}
