/*
 * mobileactivation.c
 * com.apple.mobileactivationd service implementation.
 *
 * Copyright (c) 2016-2017 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
#include <string.h>
#include <stdlib.h>
#include "mobileactivation.h"
#include "property_list_service.h"
#include "common/debug.h"

/**
 * Convert a property_list_service_error_t value to a mobileactivation_error_t value.
 * Used internally to get correct error codes.
 *
 * @param err An property_list_service_error_t error code
 *
 * @return A matching mobileactivation_error_t error code,
 *     MOBILEACTIVATION_E_UNKNOWN_ERROR otherwise.
 */
static mobileactivation_error_t mobileactivation_error(property_list_service_error_t err)
{
	switch (err) {
		case PROPERTY_LIST_SERVICE_E_SUCCESS:
			return MOBILEACTIVATION_E_SUCCESS;
		case PROPERTY_LIST_SERVICE_E_INVALID_ARG:
			return MOBILEACTIVATION_E_INVALID_ARG;
		case PROPERTY_LIST_SERVICE_E_PLIST_ERROR:
			return MOBILEACTIVATION_E_PLIST_ERROR;
		case PROPERTY_LIST_SERVICE_E_MUX_ERROR:
			return MOBILEACTIVATION_E_MUX_ERROR;
		default:
			break;
	}
	return MOBILEACTIVATION_E_UNKNOWN_ERROR;
}

LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobileactivation_client_t *client)
{
	if (!device || !service || service->port == 0 || !client || *client) {
		return MOBILEACTIVATION_E_INVALID_ARG;
	}

	property_list_service_client_t plistclient = NULL;
	if (property_list_service_client_new(device, service, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		return MOBILEACTIVATION_E_MUX_ERROR;
	}

	/* create client object */
	mobileactivation_client_t client_loc = (mobileactivation_client_t) malloc(sizeof(struct mobileactivation_client_private));
	client_loc->parent = plistclient;

	/* all done, return success */
	*client = client_loc;
	return MOBILEACTIVATION_E_SUCCESS;
}

LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_client_start_service(idevice_t device, mobileactivation_client_t * client, const char* label)
{
	mobileactivation_error_t err = MOBILEACTIVATION_E_UNKNOWN_ERROR;
	service_client_factory_start_service(device, MOBILEACTIVATION_SERVICE_NAME, (void**)client, label, SERVICE_CONSTRUCTOR(mobileactivation_client_new), &err);
	return err;
}

LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_client_free(mobileactivation_client_t client)
{
	if (!client)
		return MOBILEACTIVATION_E_INVALID_ARG;

	if (property_list_service_client_free(client->parent) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		return MOBILEACTIVATION_E_UNKNOWN_ERROR;
	}
	free(client);
	return MOBILEACTIVATION_E_SUCCESS;
}

static plist_t plist_data_from_plist(plist_t plist)
{
	if (plist && plist_get_node_type(plist) == PLIST_DATA) {
		return plist_copy(plist);
	}
	plist_t result = NULL;
	char *xml = NULL;
	uint32_t xml_len = 0;
	plist_to_xml(plist, &xml, &xml_len);
	result = plist_new_data(xml, xml_len);
	free(xml);
	return result;
}

static mobileactivation_error_t mobileactivation_check_result(plist_t dict, const char *command)
{
	mobileactivation_error_t ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;

	if (!dict || plist_get_node_type(dict) != PLIST_DICT) {
		return MOBILEACTIVATION_E_PLIST_ERROR;
	}

	plist_t err_node = plist_dict_get_item(dict, "Error");
	if (!err_node) {
		return MOBILEACTIVATION_E_SUCCESS;
	} else {
		char *errmsg = NULL;
		plist_get_string_val(err_node, &errmsg);
		debug_info("ERROR: %s: %s", command, errmsg);
		ret = MOBILEACTIVATION_E_REQUEST_FAILED;
		free(errmsg);
	}
	return ret;
}

static mobileactivation_error_t mobileactivation_send_command_plist(mobileactivation_client_t client, plist_t command, plist_t *result)
{
	if (!client || !command)
		return MOBILEACTIVATION_E_INVALID_ARG;

	plist_t cmd = plist_dict_get_item(command, "Command");
	char* command_str = NULL;
	if (cmd) {
		plist_get_string_val(cmd, &command_str);
	}
	if (!command_str)
		return MOBILEACTIVATION_E_INVALID_ARG;

	mobileactivation_error_t ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
	*result = NULL;

	ret = mobileactivation_error(property_list_service_send_binary_plist(client->parent, command));

	plist_t dict = NULL;
	ret = mobileactivation_error(property_list_service_receive_plist(client->parent, &dict));
	if (!dict) {
		debug_info("ERROR: Did not get reply for %s command", command_str);
		free(command_str);
		return MOBILEACTIVATION_E_PLIST_ERROR;
	}

	*result = dict;
	ret = mobileactivation_check_result(dict, command_str);
	free(command_str);
	return ret;
}

static mobileactivation_error_t mobileactivation_send_command(mobileactivation_client_t client, const char* command, plist_t value, plist_t *result)
{
	if (!client || !command || !result)
		return MOBILEACTIVATION_E_INVALID_ARG;

	mobileactivation_error_t ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
	*result = NULL;

	plist_t dict = plist_new_dict();
	plist_dict_set_item(dict, "Command", plist_new_string(command));
	if (value) {
		plist_dict_set_item(dict, "Value", plist_copy(value));
	}

	ret = mobileactivation_send_command_plist(client, dict, result);
	plist_free(dict);
	return ret;
}

LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_get_activation_state(mobileactivation_client_t client, plist_t *state)
{
	if (!client || !state)
		return MOBILEACTIVATION_E_INVALID_ARG;

	plist_t result = NULL;
	mobileactivation_error_t ret = mobileactivation_send_command(client, "GetActivationStateRequest", NULL, &result);
	if (ret == MOBILEACTIVATION_E_SUCCESS) {
		plist_t node = plist_dict_get_item(result, "Value");
		if (!node) {
			debug_info("ERROR: GetActivationStateRequest command returned success but has no value in reply");
			ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
		} else {
			*state = plist_copy(node);
		}
	}
	plist_free(result);
	result = NULL;

	return ret;
}

LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_create_activation_session_info(mobileactivation_client_t client, plist_t *blob)
{
	if (!client || !blob)
		return MOBILEACTIVATION_E_INVALID_ARG;

	plist_t result = NULL;
	mobileactivation_error_t ret = mobileactivation_send_command(client, "CreateTunnel1SessionInfoRequest", NULL, &result);
	if (ret == MOBILEACTIVATION_E_SUCCESS) {
		plist_t node = plist_dict_get_item(result, "Value");
		if (!node) {
			debug_info("ERROR: CreateTunnel1SessionInfoRequest command returned success but has no value in reply");
			ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
		} else {
			*blob = plist_copy(node);
		}
	}

	return ret;
}

LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_create_activation_info(mobileactivation_client_t client, plist_t *info)
{
	if (!client || !info)
		return MOBILEACTIVATION_E_INVALID_ARG;

	plist_t result = NULL;
	mobileactivation_error_t ret = mobileactivation_send_command(client, "CreateActivationInfoRequest", NULL, &result);
	if (ret == MOBILEACTIVATION_E_SUCCESS) {
		plist_t node = plist_dict_get_item(result, "Value");
		if (!node) {
			debug_info("ERROR: CreateActivationInfoRequest command returned success but has no value in reply");
			ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
		} else {
			*info = plist_copy(node);
		}
	}
	plist_free(result);
	result = NULL;

	return ret;
}

LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_create_activation_info_with_session(mobileactivation_client_t client, plist_t handshake_response, plist_t *info)
{
	if (!client || !info)
		return MOBILEACTIVATION_E_INVALID_ARG;

	plist_t result = NULL;
	plist_t data = plist_data_from_plist(handshake_response);
	mobileactivation_error_t ret = mobileactivation_send_command(client, "CreateTunnel1ActivationInfoRequest", data, &result);
	plist_free(data);
	if (ret == MOBILEACTIVATION_E_SUCCESS) {
		plist_t node = plist_dict_get_item(result, "Value");
		if (!node) {
			debug_info("ERROR: CreateTunnel1ActivationInfoRequest command returned success but has no value in reply");
			ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;
		} else {
			*info = plist_copy(node);
		}
	}
	plist_free(result);
	result = NULL;

	return ret;
}

LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_activate(mobileactivation_client_t client, plist_t activation_record)
{
	if (!client || !activation_record)
		return MOBILEACTIVATION_E_INVALID_ARG;

	plist_t result = NULL;
	mobileactivation_error_t ret = mobileactivation_send_command(client, "HandleActivationInfoRequest", activation_record, &result);
	plist_free(result);
	result = NULL;

	return ret;
}

LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_activate_with_session(mobileactivation_client_t client, plist_t activation_record, plist_t headers)
{
	if (!client || !activation_record)
		return MOBILEACTIVATION_E_INVALID_ARG;

	plist_t result = NULL;

	plist_t dict = plist_new_dict();
	plist_dict_set_item(dict, "Command", plist_new_string("HandleActivationInfoWithSessionRequest"));
	plist_dict_set_item(dict, "Value", plist_data_from_plist(activation_record));
	if (headers) {
		plist_dict_set_item(dict, "ActivationResponseHeaders", plist_copy(headers));
	}

	mobileactivation_error_t ret = mobileactivation_send_command_plist(client, dict, &result);
	plist_free(dict);
	plist_free(result);
	result = NULL;

	return ret;
}


LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_deactivate(mobileactivation_client_t client)
{
	if (!client)
		return MOBILEACTIVATION_E_INVALID_ARG;

	plist_t result = NULL;
	mobileactivation_error_t ret = mobileactivation_send_command(client, "DeactivateRequest", NULL, &result);
	plist_free(result);
	result = NULL;

	return ret;
}
