/*
 * ideviceimagemounter.c
 * Mount developer/debug disk images on the device
 *
 * Copyright (C) 2010 Nikias Bassen <nikias@gmx.li>
 *
 * 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 <stdlib.h>
#define _GNU_SOURCE 1
#define __USE_GNU 1
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include <libgen.h>
#include <time.h>
#include <sys/time.h>
#include <inttypes.h>

#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/lockdown.h>
#include <libimobiledevice/afc.h>
#include <libimobiledevice/notification_proxy.h>
#include <libimobiledevice/mobile_image_mounter.h>
#include <asprintf.h>
#include "common/utils.h"

static int list_mode = 0;
static int xml_mode = 0;
static char *udid = NULL;
static char *imagetype = NULL;

static const char PKG_PATH[] = "PublicStaging";
static const char PATH_PREFIX[] = "/private/var/mobile/Media";

typedef enum {
	DISK_IMAGE_UPLOAD_TYPE_AFC,
	DISK_IMAGE_UPLOAD_TYPE_UPLOAD_IMAGE
} disk_image_upload_type_t;

static void print_usage(int argc, char **argv)
{
	char *name = NULL;

	name = strrchr(argv[0], '/');
	printf("Usage: %s [OPTIONS] IMAGE_FILE IMAGE_SIGNATURE_FILE\n\n", (name ? name + 1: argv[0]));
	printf("Mounts the specified disk image on the device.\n\n");
	printf("  -u, --udid UDID\ttarget specific device by UDID\n");
	printf("  -l, --list\t\tList mount information\n");
	printf("  -t, --imagetype\tImage type to use, default is 'Developer'\n");
	printf("  -x, --xml\t\tUse XML output\n");
	printf("  -d, --debug\t\tenable communication debugging\n");
	printf("  -h, --help\t\tprints usage information\n");
	printf("\n");
	printf("Homepage: <" PACKAGE_URL ">\n");
}

static void parse_opts(int argc, char **argv)
{
	static struct option longopts[] = {
		{"help", no_argument, NULL, 'h'},
		{"udid", required_argument, NULL, 'u'},
		{"list", no_argument, NULL, 'l'},
		{"imagetype", required_argument, NULL, 't'},
		{"xml", no_argument, NULL, 'x'},
		{"debug", no_argument, NULL, 'd'},
		{NULL, 0, NULL, 0}
	};
	int c;

	while (1) {
		c = getopt_long(argc, argv, "hu:lt:xd", longopts, NULL);
		if (c == -1) {
			break;
		}

		switch (c) {
		case 'h':
			print_usage(argc, argv);
			exit(0);
		case 'u':
			if (!*optarg) {
				fprintf(stderr, "ERROR: UDID must not be empty!\n");
				print_usage(argc, argv);
				exit(2);
			}
			free(udid);
			udid = strdup(optarg);
			break;
		case 'l':
			list_mode = 1;
			break;
		case 't':
			if (imagetype)
				free(imagetype);
			imagetype = strdup(optarg);
			break;
		case 'x':
			xml_mode = 1;
			break;
		case 'd':
			idevice_set_debug_level(1);
			break;
		default:
			print_usage(argc, argv);
			exit(2);
		}
	}
}

static void print_xml(plist_t node)
{
	char *xml = NULL;
	uint32_t len = 0;
	plist_to_xml(node, &xml, &len);
	if (xml)
		puts(xml);
}

static ssize_t mim_upload_cb(void* buf, size_t size, void* userdata)
{
	return fread(buf, 1, size, (FILE*)userdata);
}

int main(int argc, char **argv)
{
	idevice_t device = NULL;
	lockdownd_client_t lckd = NULL;
	lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR;
	mobile_image_mounter_client_t mim = NULL;
	afc_client_t afc = NULL;
	lockdownd_service_descriptor_t service = NULL;
	int res = -1;
	char *image_path = NULL;
	size_t image_size = 0;
	char *image_sig_path = NULL;

	parse_opts(argc, argv);

	argc -= optind;
	argv += optind;

	if (!list_mode) {
		if (argc < 1) {
			printf("ERROR: No IMAGE_FILE has been given!\n");
			return -1;
		}
		image_path = strdup(argv[0]);
		if (argc >= 2) {
			image_sig_path = strdup(argv[1]);
		} else {
			if (asprintf(&image_sig_path, "%s.signature", image_path) < 0) {
				printf("Out of memory?!\n");
				return -1;
			}
		}
	}

	if (IDEVICE_E_SUCCESS != idevice_new(&device, udid)) {
		printf("No device found, is it plugged in?\n");
		return -1;
	}

	if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &lckd, "ideviceimagemounter"))) {
		printf("ERROR: Could not connect to lockdown, error code %d.\n", ldret);
		goto leave;
	}

	plist_t pver = NULL;
	char *product_version = NULL;
	lockdownd_get_value(lckd, NULL, "ProductVersion", &pver);
	if (pver && plist_get_node_type(pver) == PLIST_STRING) {
		plist_get_string_val(pver, &product_version);
	}
	disk_image_upload_type_t disk_image_upload_type = DISK_IMAGE_UPLOAD_TYPE_AFC;
	int product_version_major = 0;
	int product_version_minor = 0;
	if (product_version) {
		if (sscanf(product_version, "%d.%d.%*d", &product_version_major, &product_version_minor) == 2) {
			if (product_version_major >= 7)
				disk_image_upload_type = DISK_IMAGE_UPLOAD_TYPE_UPLOAD_IMAGE;
		}
	}

	lockdownd_start_service(lckd, "com.apple.mobile.mobile_image_mounter", &service);

	if (!service || service->port == 0) {
		printf("ERROR: Could not start mobile_image_mounter service!\n");
		goto leave;
	}

	if (mobile_image_mounter_new(device, service, &mim) != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
		printf("ERROR: Could not connect to mobile_image_mounter!\n");
		goto leave;
	}

	if (service) {
		lockdownd_service_descriptor_free(service);
		service = NULL;
	}

	if (!list_mode) {
		struct stat fst;
		if (disk_image_upload_type == DISK_IMAGE_UPLOAD_TYPE_AFC) {
			if ((lockdownd_start_service(lckd, "com.apple.afc", &service) !=
				 LOCKDOWN_E_SUCCESS) || !service || !service->port) {
				fprintf(stderr, "Could not start com.apple.afc!\n");
				goto leave;
			}
			if (afc_client_new(device, service, &afc) != AFC_E_SUCCESS) {
				fprintf(stderr, "Could not connect to AFC!\n");
				goto leave;
			}
			if (service) {
				lockdownd_service_descriptor_free(service);
				service = NULL;
			}
		}
		if (stat(image_path, &fst) != 0) {
			fprintf(stderr, "ERROR: stat: %s: %s\n", image_path, strerror(errno));
			goto leave;
		}
		image_size = fst.st_size;
		if (stat(image_sig_path, &fst) != 0) {
			fprintf(stderr, "ERROR: stat: %s: %s\n", image_sig_path, strerror(errno));
			goto leave;
		}
	}

	lockdownd_client_free(lckd);
	lckd = NULL;

	mobile_image_mounter_error_t err = MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR;
	plist_t result = NULL;

	if (list_mode) {
		/* list mounts mode */
		if (!imagetype) {
			imagetype = strdup("Developer");
		}
		err = mobile_image_mounter_lookup_image(mim, imagetype, &result);
		free(imagetype);
		if (err == MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
			res = 0;
			if (xml_mode) {
				print_xml(result);
			} else {
				plist_print_to_stream(result, stdout);
			}
		} else {
			printf("Error: lookup_image returned %d\n", err);
		}
	} else {
		char sig[8192];
		size_t sig_length = 0;
		FILE *f = fopen(image_sig_path, "rb");
		if (!f) {
			fprintf(stderr, "Error opening signature file '%s': %s\n", image_sig_path, strerror(errno));
			goto leave;
		}
		sig_length = fread(sig, 1, sizeof(sig), f);
		fclose(f);
		if (sig_length == 0) {
			fprintf(stderr, "Could not read signature from file '%s'\n", image_sig_path);
			goto leave;
		}

		f = fopen(image_path, "rb");
		if (!f) {
			fprintf(stderr, "Error opening image file '%s': %s\n", image_path, strerror(errno));
			goto leave;
		}

		char *targetname = NULL;
		if (asprintf(&targetname, "%s/%s", PKG_PATH, "staging.dimage") < 0) {
			fprintf(stderr, "Out of memory!?\n");
			goto leave;
		}
		char *mountname = NULL;
		if (asprintf(&mountname, "%s/%s", PATH_PREFIX, targetname) < 0) {
			fprintf(stderr, "Out of memory!?\n");
			goto leave;
		}


		if (!imagetype) {
			imagetype = strdup("Developer");
		}

		switch(disk_image_upload_type) {
			case DISK_IMAGE_UPLOAD_TYPE_UPLOAD_IMAGE:
				printf("Uploading %s\n", image_path);
				err = mobile_image_mounter_upload_image(mim, imagetype, image_size, sig, sig_length, mim_upload_cb, f);
				break;
			case DISK_IMAGE_UPLOAD_TYPE_AFC:
			default:
				printf("Uploading %s --> afc:///%s\n", image_path, targetname);
				char **strs = NULL;
				if (afc_get_file_info(afc, PKG_PATH, &strs) != AFC_E_SUCCESS) {
					if (afc_make_directory(afc, PKG_PATH) != AFC_E_SUCCESS) {
						fprintf(stderr, "WARNING: Could not create directory '%s' on device!\n", PKG_PATH);
					}
				}
				if (strs) {
					int i = 0;
					while (strs[i]) {
						free(strs[i]);
						i++;
					}
					free(strs);
				}

				uint64_t af = 0;
				if ((afc_file_open(afc, targetname, AFC_FOPEN_WRONLY, &af) !=
					 AFC_E_SUCCESS) || !af) {
					fclose(f);
					fprintf(stderr, "afc_file_open on '%s' failed!\n", targetname);
					goto leave;
				}

				char buf[8192];
				size_t amount = 0;
				do {
					amount = fread(buf, 1, sizeof(buf), f);
					if (amount > 0) {
						uint32_t written, total = 0;
						while (total < amount) {
							written = 0;
							if (afc_file_write(afc, af, buf + total, amount - total, &written) !=
								AFC_E_SUCCESS) {
								fprintf(stderr, "AFC Write error!\n");
								break;
							}
							total += written;
						}
						if (total != amount) {
							fprintf(stderr, "Error: wrote only %d of %d\n", total,
									(unsigned int)amount);
							afc_file_close(afc, af);
							fclose(f);
							goto leave;
						}
					}
				}
				while (amount > 0);

				afc_file_close(afc, af);
				break;
		}

		fclose(f);

		if (err != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
			if (err == MOBILE_IMAGE_MOUNTER_E_DEVICE_LOCKED) {
				printf("ERROR: Device is locked, can't mount. Unlock device and try again.\n");
			} else {
				printf("ERROR: Unknown error occurred, can't mount.\n");
			}
			goto error_out;
		}
		printf("done.\n");

		printf("Mounting...\n");
		err = mobile_image_mounter_mount_image(mim, mountname, sig, sig_length, imagetype, &result);
		free(imagetype);
		if (err == MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
			if (result) {
				plist_t node = plist_dict_get_item(result, "Status");
				if (node) {
					char *status = NULL;
					plist_get_string_val(node, &status);
					if (status) {
						if (!strcmp(status, "Complete")) {
							printf("Done.\n");
							res = 0;
						} else {
							printf("unexpected status value:\n");
							if (xml_mode) {
								print_xml(result);
							} else {
								plist_print_to_stream(result, stdout);
							}
						}
						free(status);
					} else {
						printf("unexpected result:\n");
						if (xml_mode) {
							print_xml(result);
						} else {
							plist_print_to_stream(result, stdout);
						}
					}
				}
				node = plist_dict_get_item(result, "Error");
				if (node) {
					char *error = NULL;
					plist_get_string_val(node, &error);
					if (error) {
						printf("Error: %s\n", error);
						free(error);
					} else {
						printf("unexpected result:\n");
						if (xml_mode) {
							print_xml(result);
						} else {
							plist_print_to_stream(result, stdout);
						}
					}

				} else {
					if (xml_mode) {
						print_xml(result);
					} else {
						plist_print_to_stream(result, stdout);
					}
				}
			}
		} else {
			printf("Error: mount_image returned %d\n", err);

		}
	}

	if (result) {
		plist_free(result);
	}

error_out:
	/* perform hangup command */
	mobile_image_mounter_hangup(mim);
	/* free client */
	mobile_image_mounter_free(mim);

leave:
	if (afc) {
		afc_client_free(afc);
	}
	if (lckd) {
		lockdownd_client_free(lckd);
	}
	idevice_free(device);

	if (image_path)
			free(image_path);
	if (image_sig_path)
		free(image_sig_path);

	return res;
}
