/*
 * webinspector.c 
 * com.apple.webinspector service implementation.
 * 
 * Copyright (c) 2013 Yury Melnichek 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>
#include <plist/plist.h>

#include "webinspector.h"
#include "lockdown.h"
#include "common/debug.h"

/**
 * Convert a property_list_service_error_t value to a webinspector_error_t value.
 * Used internally to get correct error codes.
 *
 * @param err An property_list_service_error_t error code
 *
 * @return A matching webinspector_error_t error code,
 *     WEBINSPECTOR_E_UNKNOWN_ERROR otherwise.
 */
static webinspector_error_t webinspector_error(property_list_service_error_t err)
{
	switch (err) {
		case PROPERTY_LIST_SERVICE_E_SUCCESS:
			return WEBINSPECTOR_E_SUCCESS;
		case PROPERTY_LIST_SERVICE_E_INVALID_ARG:
			return WEBINSPECTOR_E_INVALID_ARG;
		case PROPERTY_LIST_SERVICE_E_PLIST_ERROR:
			return WEBINSPECTOR_E_PLIST_ERROR;
		case PROPERTY_LIST_SERVICE_E_MUX_ERROR:
			return WEBINSPECTOR_E_MUX_ERROR;
		case PROPERTY_LIST_SERVICE_E_SSL_ERROR:
			return WEBINSPECTOR_E_SSL_ERROR;
		default:
			break;
	}
	return WEBINSPECTOR_E_UNKNOWN_ERROR;
}

/**
 * Connects to the webinspector service on the specified device.
 *
 * @param device The device to connect to.
 * @param service The service descriptor returned by lockdownd_start_service.
 * @param client Pointer that will point to a newly allocated
 *     webinspector_client_t upon successful return. Must be freed using
 *     webinspector_client_free() after use.
 *
 * @return WEBINSPECTOR_E_SUCCESS on success, WEBINSPECTOR_E_INVALID_ARG when
 *     client is NULL, or an WEBINSPECTOR_E_* error code otherwise.
 */
webinspector_error_t webinspector_client_new(idevice_t device, lockdownd_service_descriptor_t service, webinspector_client_t * client)
{
	*client = NULL;

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

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

	property_list_service_client_t plclient = NULL;
	webinspector_error_t ret = webinspector_error(property_list_service_client_new(device, service, &plclient));
	if (ret != WEBINSPECTOR_E_SUCCESS) {
		debug_info("Creating a property list client failed. Error: %i", ret);
		return ret;
	}

	webinspector_client_t client_loc = (webinspector_client_t) malloc(sizeof(struct webinspector_client_private));
	client_loc->parent = plclient;

	*client = client_loc;

	debug_info("webinspector_client successfully created.");
	return 0;
}

/**
 * Starts a new webinspector service on the specified device and connects to it.
 *
 * @param device The device to connect to.
 * @param client Pointer that will point to a newly allocated
 *     webinspector_client_t upon successful return. Must be freed using
 *     webinspector_client_free() after use.
 * @param label The label to use for communication. Usually the program name.
 *  Pass NULL to disable sending the label in requests to lockdownd.
 *
 * @return WEBINSPECTOR_E_SUCCESS on success, or an WEBINSPECTOR_E_* error
 *     code otherwise.
 */
webinspector_error_t webinspector_client_start_service(idevice_t device, webinspector_client_t * client, const char* label)
{
	webinspector_error_t err = WEBINSPECTOR_E_UNKNOWN_ERROR;
	service_client_factory_start_service(device, WEBINSPECTOR_SERVICE_NAME, (void**)client, label, SERVICE_CONSTRUCTOR(webinspector_client_new), &err);
	return err;
}

/**
 * Disconnects a webinspector client from the device and frees up the
 * webinspector client data.
 *
 * @param client The webinspector client to disconnect and free.
 *
 * @return WEBINSPECTOR_E_SUCCESS on success, WEBINSPECTOR_E_INVALID_ARG when
 *     client is NULL, or an WEBINSPECTOR_E_* error code otherwise.
 */
webinspector_error_t webinspector_client_free(webinspector_client_t client)
{
	if (!client)
		return WEBINSPECTOR_E_INVALID_ARG;

	webinspector_error_t err = webinspector_error(property_list_service_client_free(client->parent));
	free(client);

	return err;
}

/**
 * Sends a plist to the service.
 *
 * @param client The webinspector client
 * @param plist The plist to send
 *
 * @return DIAGNOSTICS_RELAY_E_SUCCESS on success,
 *  DIAGNOSTICS_RELAY_E_INVALID_ARG when client or plist is NULL
 */
webinspector_error_t webinspector_send(webinspector_client_t client, plist_t plist)
{
	webinspector_error_t res = WEBINSPECTOR_E_UNKNOWN_ERROR;

	uint32_t offset = 0;
	int is_final_message = 0;

	char *packet = NULL;
	uint32_t packet_length = 0;

	debug_info("Sending webinspector message...");
	debug_plist(plist);

	/* convert plist to packet */
	plist_to_bin(plist, &packet, &packet_length);
	if (!packet || packet_length == 0) {
		debug_info("Error converting plist to binary.");
		return res;
	}

	do {	
		/* determine if we need to send partial messages */
		if (packet_length < WEBINSPECTOR_PARTIAL_PACKET_CHUNK_SIZE) {
			is_final_message = 1;
		} else {
			/* send partial packet */
			is_final_message = 0;
		}

		plist_t outplist = plist_new_dict();
		if (!is_final_message) {
			/* split packet into partial chunks */
			plist_dict_set_item(outplist, "WIRPartialMessageKey", plist_new_data(packet + offset, WEBINSPECTOR_PARTIAL_PACKET_CHUNK_SIZE));
			offset += WEBINSPECTOR_PARTIAL_PACKET_CHUNK_SIZE;
			packet_length -= WEBINSPECTOR_PARTIAL_PACKET_CHUNK_SIZE;
		} else {
			/* send final chunk */
			plist_dict_set_item(outplist, "WIRFinalMessageKey", plist_new_data(packet + offset, packet_length));
			offset += packet_length;
			packet_length -= packet_length;
		}

		res = webinspector_error(property_list_service_send_binary_plist(client->parent, outplist));
		plist_free(outplist);
		outplist = NULL;
		if (res != WEBINSPECTOR_E_SUCCESS) {
			debug_info("Sending plist failed with error %d", res);
			return res;
		}
	} while(packet_length > 0);

	free(packet);
	packet = NULL;

	return res;
}

/**
 * Receives a plist from the service.
 *
 * @param client The webinspector client
 * @param plist The plist to store the received data
 *
 * @return DIAGNOSTICS_RELAY_E_SUCCESS on success,
 *  DIAGNOSTICS_RELAY_E_INVALID_ARG when client or plist is NULL
 */
webinspector_error_t webinspector_receive(webinspector_client_t client, plist_t * plist)
{
	return webinspector_receive_with_timeout(client, plist, 5000);
}

/**
 * Receives a plist using the given webinspector client.
 *
 * @param client The webinspector client to use for receiving
 * @param plist pointer to a plist_t that will point to the received plist
 *      upon successful return
 * @param timeout Maximum time in milliseconds to wait for data.
 *
 * @return WEBINSPECTOR_E_SUCCESS on success,
 *      WEBINSPECTOR_E_INVALID_ARG when client or *plist is NULL,
 *      WEBINSPECTOR_E_PLIST_ERROR when the received data cannot be
 *      converted to a plist, WEBINSPECTOR_E_MUX_ERROR when a
 *      communication error occurs, or WEBINSPECTOR_E_UNKNOWN_ERROR
 *      when an unspecified error occurs.
 */
webinspector_error_t webinspector_receive_with_timeout(webinspector_client_t client, plist_t * plist, uint32_t timeout_ms)
{
	webinspector_error_t res = WEBINSPECTOR_E_UNKNOWN_ERROR;
	plist_t message = NULL;
	plist_t key = NULL;

	int is_final_message = 1;

	char* buffer = NULL;
	uint64_t length = 0;

	char* packet = NULL;
	char* newpacket = NULL;
	uint64_t packet_length = 0;

	debug_info("Receiving webinspector message...");

	do {
		/* receive message */
		res = webinspector_error(property_list_service_receive_plist_with_timeout(client->parent, &message, timeout_ms));
		if (res != WEBINSPECTOR_E_SUCCESS || !message) {
			debug_info("Could not receive message, error %d", res);
			plist_free(message);
			return WEBINSPECTOR_E_MUX_ERROR;
		}

		/* get message key */
		key = plist_dict_get_item(message, "WIRFinalMessageKey");
		if (!key) {
			key = plist_dict_get_item(message, "WIRPartialMessageKey");
			if (!key) {
				debug_info("ERROR: Unable to read message key.");
				plist_free(message);
				return WEBINSPECTOR_E_PLIST_ERROR;
			}
			is_final_message = 0;
		} else {
			is_final_message = 1;
		}

		/* read partial data */
		plist_get_data_val(key, &buffer, &length);
		if (!buffer || length == 0 || length > 0xFFFFFFFF) {
			debug_info("ERROR: Unable to get the inner plist binary data.");
			free(packet);
			free(buffer);
			return WEBINSPECTOR_E_PLIST_ERROR;
		}

		/* (re)allocate packet data */
		if (!packet) {
			packet = (char*)malloc(length * sizeof(char));
		} else {
			newpacket = (char*)realloc(packet, (packet_length + length) * sizeof(char));
			packet = newpacket;
		}

		/* copy partial data into final packet data */
		memcpy(packet + packet_length, buffer, length);

		/* cleanup buffer */
		free(buffer);
		buffer = NULL;

		if (message) {
			plist_free(message);
			message = NULL;
		}

		/* adjust packet length */
		packet_length += length;
		length = 0;
	} while(!is_final_message);

	/* read final message */
	if (packet_length) {
		plist_from_bin(packet, (uint32_t)packet_length, plist);
		if (!*plist) {
			debug_info("Error restoring the final plist.");
			free(packet);
			return WEBINSPECTOR_E_PLIST_ERROR;
		}

		debug_plist(*plist);
	}

	if (packet) {
		free(packet);
	}

	return res;
}
