/*
 * debugserver.c
 * com.apple.debugserver service implementation.
 *
 * Copyright (c) 2019 Nikias Bassen, All Rights Reserved.
 * 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
#include <string.h>
#include <stdlib.h>
#define _GNU_SOURCE 1
#define __USE_GNU 1
#include <stdio.h>

#include <libimobiledevice-glue/utils.h>

#include "debugserver.h"
#include "lockdown.h"
#include "common/debug.h"
#include "asprintf.h"

/**
 * Convert a service_error_t value to a debugserver_error_t value.
 * Used internally to get correct error codes.
 *
 * @param err An service_error_t error code
 *
 * @return A matching debugserver_error_t error code,
 *     DEBUGSERVER_E_UNKNOWN_ERROR otherwise.
 */
static debugserver_error_t debugserver_error(service_error_t err)
{
	switch (err) {
		case SERVICE_E_SUCCESS:
			return DEBUGSERVER_E_SUCCESS;
		case SERVICE_E_INVALID_ARG:
			return DEBUGSERVER_E_INVALID_ARG;
		case SERVICE_E_MUX_ERROR:
			return DEBUGSERVER_E_MUX_ERROR;
		case SERVICE_E_SSL_ERROR:
			return DEBUGSERVER_E_SSL_ERROR;
		case SERVICE_E_TIMEOUT:
			return DEBUGSERVER_E_TIMEOUT;
		default:
			break;
	}
	return DEBUGSERVER_E_UNKNOWN_ERROR;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_new(idevice_t device, lockdownd_service_descriptor_t service, debugserver_client_t* client)
{
	*client = NULL;

	if (!device || !service || service->port == 0 || !client || *client) {
		debug_info("Incorrect parameter passed to debugserver_client_new.");
		return DEBUGSERVER_E_INVALID_ARG;
	}

	debug_info("Creating debugserver_client, port = %d.", service->port);

	service_client_t parent = NULL;
	debugserver_error_t ret = debugserver_error(service_client_new(device, service, &parent));
	if (ret != DEBUGSERVER_E_SUCCESS) {
		debug_info("Creating base service client failed. Error: %i", ret);
		return ret;
	}

	if (service->identifier && (strcmp(service->identifier, DEBUGSERVER_SECURE_SERVICE_NAME) != 0)) {
		service_disable_bypass_ssl(parent, 1);
	}

	debugserver_client_t client_loc = (debugserver_client_t) malloc(sizeof(struct debugserver_client_private));
	client_loc->parent = parent;
	client_loc->noack_mode = 0;
	client_loc->cancel_receive = NULL;
	client_loc->receive_loop_timeout = 1000;

	*client = client_loc;

	debug_info("debugserver_client successfully created.");
	return DEBUGSERVER_E_SUCCESS;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_start_service(idevice_t device, debugserver_client_t * client, const char* label)
{
	debugserver_error_t err = DEBUGSERVER_E_UNKNOWN_ERROR;
	service_client_factory_start_service(device, DEBUGSERVER_SECURE_SERVICE_NAME, (void**)client, label, SERVICE_CONSTRUCTOR(debugserver_client_new), &err);
	if (err != DEBUGSERVER_E_SUCCESS) {
		err = DEBUGSERVER_E_UNKNOWN_ERROR;
		service_client_factory_start_service(device, DEBUGSERVER_SERVICE_NAME, (void**)client, label, SERVICE_CONSTRUCTOR(debugserver_client_new), &err);
	}
	return err;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_free(debugserver_client_t client)
{
	if (!client)
		return DEBUGSERVER_E_INVALID_ARG;

	debugserver_error_t err = debugserver_error(service_client_free(client->parent));
	client->parent = NULL;
	free(client);

	return err;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_send(debugserver_client_t client, const char* data, uint32_t size, uint32_t *sent)
{
	debugserver_error_t res = DEBUGSERVER_E_UNKNOWN_ERROR;
	int bytes = 0;

	if (!client || !data || (size == 0)) {
		return DEBUGSERVER_E_INVALID_ARG;
	}

	debug_info("sending %d bytes", size);
	res = debugserver_error(service_send(client->parent, data, size, (uint32_t*)&bytes));
	if (bytes <= 0) {
		debug_info("ERROR: sending to device failed.");
	}
	if (sent) {
		*sent = (uint32_t)bytes;
	}

	return res;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_receive_with_timeout(debugserver_client_t client, char* data, uint32_t size, uint32_t *received, unsigned int timeout)
{
	debugserver_error_t res = DEBUGSERVER_E_UNKNOWN_ERROR;
	int bytes = 0;

	if (!client || !data || (size == 0)) {
		return DEBUGSERVER_E_INVALID_ARG;
	}

	res = debugserver_error(service_receive_with_timeout(client->parent, data, size, (uint32_t*)&bytes, timeout));
	if (bytes <= 0 && res != DEBUGSERVER_E_TIMEOUT) {
		debug_info("Could not read data, error %d", res);
	}
	if (received) {
		*received = (uint32_t)bytes;
	}

	return (bytes > 0) ? DEBUGSERVER_E_SUCCESS : res;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_receive(debugserver_client_t client, char* data, uint32_t size, uint32_t *received)
{
	debugserver_error_t res = DEBUGSERVER_E_UNKNOWN_ERROR;
	do {
		/* Is this allowed to return DEBUGSERVER_E_TIMEOUT and also set data and received? */
		res = debugserver_client_receive_with_timeout(client, data, size, received, client->receive_loop_timeout);
	} while (res == DEBUGSERVER_E_TIMEOUT && client->cancel_receive != NULL && !client->cancel_receive());
	return res;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_command_new(const char* name, int argc, char* argv[], debugserver_command_t* command)
{
	int i;
	debugserver_command_t tmp = (debugserver_command_t) malloc(sizeof(struct debugserver_command_private));

	/* copy name */
	tmp->name = strdup(name);

	/* copy arguments */
	tmp->argc = argc;
	tmp->argv = NULL;
	if (argc > 0) {
		tmp->argv = malloc(sizeof(char*) * (argc + 2));
		for (i = 0; i < argc; i++) {
			tmp->argv[i] = strdup(argv[i]);
		}
		tmp->argv[i+1] = NULL;
	}

	/* return */
	*command = tmp;

	return DEBUGSERVER_E_SUCCESS;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_command_free(debugserver_command_t command)
{
	int i;
	debugserver_error_t res = DEBUGSERVER_E_UNKNOWN_ERROR;

	if (!command)
		return DEBUGSERVER_E_INVALID_ARG;

	if (command) {
		if (command->name)
			free(command->name);
		if (command->argv && command->argc) {
			for (i = 0; i < command->argc; i++) {
				free(command->argv[i]);
			}
			free(command->argv);
		}
		free(command);
		res = DEBUGSERVER_E_SUCCESS;
	}

	return res;
}

static int debugserver_hex2int(char c)
{
	if (c >= '0' && c <= '9')
		return c - '0';
	else if (c >= 'a' && c <= 'f')
		return 10 + c - 'a';
	else if (c >= 'A' && c <= 'F')
		return 10 + c - 'A';
	else
		return c;
}

static char debugserver_int2hex(int x)
{
	const char *hexchars = "0123456789ABCDEF";
	return hexchars[x];
}

#define DEBUGSERVER_HEX_ENCODE_FIRST_BYTE(byte) debugserver_int2hex((byte >> 0x4) & 0xf)
#define DEBUGSERVER_HEX_ENCODE_SECOND_BYTE(byte) debugserver_int2hex(byte & 0xf)
#define DEBUGSERVER_HEX_DECODE_FIRST_BYTE(byte) ((byte >> 0x4) & 0xf)
#define DEBUGSERVER_HEX_DECODE_SECOND_BYTE(byte) (byte & 0xf)

static uint32_t debugserver_get_checksum_for_buffer(const char* buffer, uint32_t size)
{
	uint32_t checksum = 0;
	uint32_t i;

	for (i = 0; i < size; i++) {
		checksum += buffer[i];
	}

	return checksum;
}

static int debugserver_response_is_checksum_valid(const char* response, uint32_t size)
{
	uint32_t checksum = 0;
	if ((size - DEBUGSERVER_CHECKSUM_HASH_LENGTH - 1) > 0)
		checksum = debugserver_get_checksum_for_buffer(&response[1], size - DEBUGSERVER_CHECKSUM_HASH_LENGTH - 1);

	debug_info("checksum: 0x%x", checksum);

	if ((unsigned)debugserver_hex2int(response[size - 2]) != DEBUGSERVER_HEX_DECODE_FIRST_BYTE(checksum))
		return 0;

	if ((unsigned)debugserver_hex2int(response[size - 1]) != DEBUGSERVER_HEX_DECODE_SECOND_BYTE(checksum))
		return 0;

	debug_info("valid checksum");

	return 1;
}

LIBIMOBILEDEVICE_API void debugserver_encode_string(const char* buffer, char** encoded_buffer, uint32_t* encoded_length)
{
	uint32_t position;
	uint32_t index;
	uint32_t length = strlen(buffer);
	*encoded_length = (2 * length) + DEBUGSERVER_CHECKSUM_HASH_LENGTH + 1;

	*encoded_buffer = malloc(sizeof(char) * (*encoded_length));
	memset(*encoded_buffer, '\0', *encoded_length);
	for (position = 0, index = 0; index < length; index++) {
		position = (index * (2 * sizeof(char)));
		(*encoded_buffer)[position] = DEBUGSERVER_HEX_ENCODE_FIRST_BYTE(buffer[index]);
		(*encoded_buffer)[position + 1] = DEBUGSERVER_HEX_ENCODE_SECOND_BYTE(buffer[index]);
	}
}

LIBIMOBILEDEVICE_API void debugserver_decode_string(const char *encoded_buffer, size_t encoded_length, char** buffer)
{
	*buffer = malloc(sizeof(char) * ((encoded_length / 2)+1));
	char* t = *buffer;
	const char *f = encoded_buffer;
	const char *fend = f + encoded_length;
	while (f < fend) {
		*t++ = debugserver_hex2int(*f) << 4 | debugserver_hex2int(f[1]);
		f += 2;
	}
	*t = '\0';
}

static void debugserver_format_command(const char* prefix, const char* command, const char* arguments, int calculate_checksum, char** buffer, uint32_t* size)
{
	char checksum_hash[DEBUGSERVER_CHECKSUM_HASH_LENGTH + 1] = {'#', '0', '0', '\0'};
	char* encoded = NULL;
	uint32_t encoded_length = 0;

	if (arguments) {
		/* arguments must be hex encoded */
		debugserver_encode_string(arguments, &encoded, &encoded_length);
	} else {
		encoded = NULL;
	}

	char* encoded_command = string_concat(command, encoded, NULL);
	encoded_length = strlen(encoded_command);

	if (calculate_checksum) {
		uint32_t checksum = debugserver_get_checksum_for_buffer(encoded_command, encoded_length);
		checksum_hash[1] = DEBUGSERVER_HEX_ENCODE_FIRST_BYTE(checksum);
		checksum_hash[2] = DEBUGSERVER_HEX_ENCODE_SECOND_BYTE(checksum);
	}

	*buffer = string_concat(prefix, encoded_command, checksum_hash, NULL);
	*size = strlen(prefix) + strlen(encoded_command) + DEBUGSERVER_CHECKSUM_HASH_LENGTH;

	debug_info("formatted command: %s size: %d checksum: 0x%s", *buffer, *size, checksum_hash);

	if (encoded_command)
		free(encoded_command);

	if (encoded)
		free(encoded);
}

static debugserver_error_t debugserver_client_send_ack(debugserver_client_t client)
{
	debug_info("sending ACK");
	return debugserver_client_send(client, "+", sizeof(char), NULL);
}

static debugserver_error_t debugserver_client_send_noack(debugserver_client_t client)
{
	debug_info("sending !ACK");
	return debugserver_client_send(client, "-", sizeof(char), NULL);
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_set_ack_mode(debugserver_client_t client, int enabled)
{
	if (!client)
		return DEBUGSERVER_E_INVALID_ARG;

	client->noack_mode = (enabled == 0)? 1: 0;

	debug_info("ack mode: %s", client->noack_mode == 0 ? "on": "off");

	return DEBUGSERVER_E_SUCCESS;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_set_receive_params(debugserver_client_t client, int (*cancel_receive)(), int receive_loop_timeout)
{
	if (!client)
		return DEBUGSERVER_E_INVALID_ARG;

	client->cancel_receive = cancel_receive;
	client->receive_loop_timeout = receive_loop_timeout;

	debug_info("receive params: cancel_receive %s, receive_loop_timeout %dms", (client->cancel_receive == NULL ? "unset": "set"), client->receive_loop_timeout);

	return DEBUGSERVER_E_SUCCESS;
}

static debugserver_error_t debugserver_client_receive_internal_char(debugserver_client_t client, char* received_char)
{
	debugserver_error_t res = DEBUGSERVER_E_SUCCESS;
	uint32_t bytes = 0;

	/* we loop here as we expect an answer */
	res = debugserver_client_receive(client, received_char, sizeof(char), &bytes);
	if (res != DEBUGSERVER_E_SUCCESS) {
		return res;
	}
	if (bytes != 1) {
		debug_info("received %d bytes when asking for %d!", bytes, sizeof(char));
		return DEBUGSERVER_E_UNKNOWN_ERROR;
	}
	return res;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_receive_response(debugserver_client_t client, char** response, size_t* response_size)
{
	debugserver_error_t res = DEBUGSERVER_E_SUCCESS;

	char data = '\0';
	int skip_prefix = 0;

	char* buffer = malloc(1024);
	uint32_t buffer_size = 0;
	uint32_t buffer_capacity = 1024;

	if (response)
		*response = NULL;

	if (!client->noack_mode) {
		debug_info("attempting to receive ACK (+)");
		res = debugserver_client_receive_internal_char(client, &data);
		if (res != DEBUGSERVER_E_SUCCESS) {
			goto cleanup;
		}
		if (data == '+') {
			debug_info("received ACK (+)");
		} else if (data == '$') {
			debug_info("received prefix ($)");
			buffer[0] = '$';
			buffer_size = 1;
			skip_prefix = 1;
		} else {
			debug_info("unrecognized response when looking for ACK: %c", data);
			goto cleanup;
		}
	}

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

	if (!skip_prefix) {
		debug_info("attempting to receive prefix ($)");
		res = debugserver_client_receive_internal_char(client, &data);
		if (res != DEBUGSERVER_E_SUCCESS) {
			goto cleanup;
		}
		if (data == '$') {
			debug_info("received prefix ($)");
			buffer[0] = '$';
			buffer_size = 1;
		} else {
			debug_info("unrecognized response when looking for prefix: %c", data);
			goto cleanup;
		}
	}

	uint32_t checksum_length = DEBUGSERVER_CHECKSUM_HASH_LENGTH;
	int receiving_checksum_response = 0;
	debug_info("attempting to read up response until checksum");

	while ((checksum_length > 0)) {
		res = debugserver_client_receive_internal_char(client, &data);
		if (res != DEBUGSERVER_E_SUCCESS) {
			goto cleanup;
		}
		if (data == '#') {
			receiving_checksum_response = 1;
		}
		if (receiving_checksum_response) {
			checksum_length--;
		}
		if (buffer_size + 1 >= buffer_capacity) {
			char* newbuffer = realloc(buffer, buffer_capacity+1024);
			if (!newbuffer) {
				return DEBUGSERVER_E_UNKNOWN_ERROR;
			}
			buffer = newbuffer;
			buffer_capacity += 1024;
		}
		buffer[buffer_size] = data;
		buffer_size += sizeof(char);
	}
	debug_info("validating response checksum...");
	if (client->noack_mode || debugserver_response_is_checksum_valid(buffer, buffer_size)) {
		if (response) {
			/* assemble response string */
			uint32_t resp_size = sizeof(char) * (buffer_size - DEBUGSERVER_CHECKSUM_HASH_LENGTH - 1);
			*response = (char*)malloc(resp_size + 1);
			memcpy(*response, buffer + 1, resp_size);
			(*response)[resp_size] = '\0';
			if (response_size) *response_size = resp_size;
		}
		if (!client->noack_mode) {
			/* confirm valid command */
			debugserver_client_send_ack(client);
		}
	} else {
		/* response was invalid */
		res = DEBUGSERVER_E_RESPONSE_ERROR;
		if (!client->noack_mode) {
			/* report invalid command */
			debugserver_client_send_noack(client);
		}
	}

cleanup:
	if (response) {
		debug_info("response: %s", *response);
	}

	if (buffer)
		free(buffer);

	return res;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_send_command(debugserver_client_t client, debugserver_command_t command, char** response, size_t* response_size)
{
	debugserver_error_t res = DEBUGSERVER_E_SUCCESS;
	int i;
	uint32_t bytes = 0;

	char* send_buffer = NULL;
	uint32_t send_buffer_size = 0;

	char* command_arguments = NULL;

	/* concat all arguments */
	for (i = 0; i < command->argc; i++) {
		debug_info("argv[%d]: %s", i, command->argv[i]);
		command_arguments = string_append(command_arguments, command->argv[i], NULL);
	}

	debug_info("command_arguments(%d): %s", command->argc, command_arguments);

	/* encode command arguments, add checksum if required and assemble entire command */
	debugserver_format_command("$", command->name, command_arguments, 1, &send_buffer, &send_buffer_size);

	debug_info("sending encoded command: %s", send_buffer);

	res = debugserver_client_send(client, send_buffer, send_buffer_size, &bytes);
	debug_info("command result: %d", res);
	if (res != DEBUGSERVER_E_SUCCESS) {
		goto cleanup;
	}

	/* receive response */
	res = debugserver_client_receive_response(client, response, response_size);
	debug_info("response result: %d", res);
	if (res != DEBUGSERVER_E_SUCCESS) {
		goto cleanup;
	}

	if (response) {
		debug_info("received response: %s", *response);
	}

	/* disable sending ack on the client */
	if (!strncmp(command->name, "QStartNoAckMode", 16)) {
		debugserver_client_set_ack_mode(client, 0);
	}

cleanup:
	if (command_arguments)
		free(command_arguments);

	if (send_buffer)
		free(send_buffer);

	return res;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_set_environment_hex_encoded(debugserver_client_t client, const char* env, char** response)
{
	if (!client || !env)
		return DEBUGSERVER_E_INVALID_ARG;

	debugserver_error_t result = DEBUGSERVER_E_UNKNOWN_ERROR;
	char* env_tmp = strdup(env);
	char* env_arg[2] = { env_tmp, NULL };

	debugserver_command_t command = NULL;
	debugserver_command_new("QEnvironmentHexEncoded:", 1, env_arg, &command);
	result = debugserver_client_send_command(client, command, response, NULL);
	debugserver_command_free(command);

	free(env_tmp);

	return result;
}

LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_set_argv(debugserver_client_t client, int argc, char* argv[], char** response)
{
	if (!client || !argc)
		return DEBUGSERVER_E_INVALID_ARG;

	debugserver_error_t result = DEBUGSERVER_E_UNKNOWN_ERROR;
	char *pkt = NULL;
	size_t pkt_len = 0;
	int i = 0;

	/* calculate total length */
	while (i < argc && argv && argv[i]) {
		char *prefix = NULL;
		int ret = asprintf(&prefix, ",%zu,%d,", strlen(argv[i]) * 2, i);
		if (ret < 0 || prefix == NULL) {
			debug_info("asprintf failed, out of memory?");
			return DEBUGSERVER_E_UNKNOWN_ERROR;
		}
		pkt_len += strlen(prefix) + strlen(argv[i]) * 2;
		free(prefix);
		i++;
	}

	/* allocate packet and initialize it */
	pkt = (char *) malloc(pkt_len + 1);
	memset(pkt, 0, pkt_len + 1);

	char *pktp = pkt;

	i = 0;
	while (i < argc && argv && argv[i]) {
		debug_info("argv[%d] = \"%s\"", i, argv[i]);

		char *prefix = NULL;
		char *m = NULL;
		size_t arg_len = strlen(argv[i]);
		size_t arg_hexlen = arg_len * 2;

		int ret = asprintf(&prefix, ",%zu,%d,", arg_hexlen, i);
		if (ret < 0 || prefix == NULL) {
			debug_info("asprintf failed, out of memory?");
			return DEBUGSERVER_E_UNKNOWN_ERROR;
		}

		m = (char *) malloc(arg_hexlen);
		char *p = m;
		char *q = (char*)argv[i];
		while (*q) {
			*p++ = DEBUGSERVER_HEX_ENCODE_FIRST_BYTE(*q);
			*p++ = DEBUGSERVER_HEX_ENCODE_SECOND_BYTE(*q);
			q++;
		}

		memcpy(pktp, prefix, strlen(prefix));
		pktp += strlen(prefix);

		memcpy(pktp, m, arg_hexlen);
		pktp += arg_hexlen;

		free(prefix);
		free(m);

		i++;
	}

	pkt[0] = 'A';

	debugserver_command_t command = NULL;
	debugserver_command_new(pkt, 0, NULL, &command);
	result = debugserver_client_send_command(client, command, response, NULL);
	debugserver_command_free(command);

	if (pkt)
		free(pkt);

	return result;
}
