/*
 *
 *  oFono - Open Source Telephony
 *
 *  Copyright (C) 2011-2012  Intel Corporation. All rights reserved.
 *  Copyright (C) 2024 Adam Pigg <adam@piggz.co.uk>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/voicecall.h>
#include <src/common.h>
#include <ell/ell.h>

#include "voice.h"

#include "qmi.h"

#include "util.h"

struct voicecall_data {
	struct qmi_service *voice;
	uint16_t major;
	uint16_t minor;
	struct l_queue *call_list;
	struct ofono_phone_number dialed;
};

struct qmi_voice_call_information_instance {
	uint8_t id;
	uint8_t state;
	uint8_t type;
	uint8_t direction;
	uint8_t mode;
	uint8_t multipart_indicator;
	uint8_t als;
} __attribute__((__packed__));

struct qmi_voice_call_information {
	uint8_t size;
	struct qmi_voice_call_information_instance instance[0];
} __attribute__((__packed__));

struct qmi_voice_remote_party_number_instance {
	uint8_t call_id;
	uint8_t presentation_indicator;
	uint8_t number_size;
	char number[0];
} __attribute__((__packed__));

struct qmi_voice_remote_party_number {
	uint8_t size;
	struct qmi_voice_remote_party_number_instance instance[0];
} __attribute__((__packed__));

static int ofono_call_compare(const void *a, const void *b, void *data)
{
	const struct ofono_call *ca = a;
	const struct ofono_call *cb = b;

	if (ca->id < cb->id)
		return -1;

	if (ca->id > cb->id)
		return 1;

	return 0;
}

static bool ofono_call_match_by_id(const void *a, const void *b)
{
	const struct ofono_call *call = a;
	unsigned int id = L_PTR_TO_UINT(b);

	return (call->id == id);
}

static bool ofono_call_match_by_status(const void *a, const void *b)
{
	const struct ofono_call *call = a;
	int status = L_PTR_TO_INT(b);

	return status == call->status;
}

static void ofono_call_list_dial_callback(struct ofono_voicecall *vc,
						int call_id)
{
	struct ofono_call *call;
	struct voicecall_data *vd = ofono_voicecall_get_data(vc);
	struct l_queue *call_list = vd->call_list;
	const struct ofono_phone_number *ph = &vd->dialed;

	/* check if call_id already present */
	call = l_queue_find(call_list, ofono_call_match_by_id,
				L_UINT_TO_PTR(call_id));

	if (call)
		return;

	call = l_new(struct ofono_call, 1);
	call->id = call_id;

	memcpy(&call->called_number, ph, sizeof(*ph));
	call->direction = CALL_DIRECTION_MOBILE_ORIGINATED;
	call->status = CALL_STATUS_DIALING;
	call->type = 0; /* voice */

	l_queue_insert(call_list, call, ofono_call_compare, NULL);

	ofono_voicecall_notify(vc, call);
}

static void ofono_call_list_notify(struct ofono_voicecall *vc,
					struct l_queue *calls)
{
	struct voicecall_data *vd = ofono_voicecall_get_data(vc);
	struct l_queue *old_calls = vd->call_list;
	struct l_queue *new_calls = calls;
	struct ofono_call *new_call, *old_call;
	const struct l_queue_entry *old_entry, *new_entry;
	uint i;

	uint loop_length =
		MAX(l_queue_length(old_calls), l_queue_length(new_calls));

	old_entry = l_queue_get_entries(old_calls);
	new_entry = l_queue_get_entries(new_calls);

	for (i = 0; i < loop_length; ++i) {
		old_call = old_entry ? old_entry->data : NULL;
		new_call = new_entry ? new_entry->data : NULL;

		if (new_call && new_call->status == CALL_STATUS_DISCONNECTED) {
			ofono_voicecall_disconnected(
				vc, new_call->id,
				OFONO_DISCONNECT_REASON_REMOTE_HANGUP, NULL);
			new_entry = new_entry->next;
			l_queue_remove(calls, new_call);
			l_free(new_call);
			continue;
		}

		if (old_call &&
				(!new_call || (new_call->id > old_call->id)))
			ofono_voicecall_disconnected(
				vc, old_call->id,
				OFONO_DISCONNECT_REASON_REMOTE_HANGUP, NULL);
		else if (new_call &&
				(!old_call || (new_call->id < old_call->id))) {
			DBG("Notify new call %d", new_call->id);
			/* new call, signal it */
			if (new_call->type == 0)
				ofono_voicecall_notify(vc, new_call);
		} else if (memcmp(new_call, old_call, sizeof(*new_call)) &&
				new_call->type == 0)
			ofono_voicecall_notify(vc, new_call);

		if (old_entry)
			old_entry = old_entry->next;
		if (new_entry)
			new_entry = new_entry->next;
	}

	l_queue_destroy(old_calls, l_free);
	vd->call_list = calls;
}

static const char *qmi_voice_call_state_name(enum qmi_voice_call_state value)
{
	switch (value) {
	case QMI_VOICE_CALL_STATE_IDLE:
		return "QMI_VOICE_CALL_STATE_IDLE";
	case QMI_VOICE_CALL_STATE_ORIG:
		return "QMI_VOICE_CALL_STATE_ORIG";
	case QMI_VOICE_CALL_STATE_INCOMING:
		return "QMI_VOICE_CALL_STATE_INCOMING";
	case QMI_VOICE_CALL_STATE_CONV:
		return "QMI_VOICE_CALL_STATE_CONV";
	case QMI_VOICE_CALL_STATE_CC_IN_PROG:
		return "QMI_VOICE_CALL_STATE_CC_IN_PROG";
	case QMI_VOICE_CALL_STATE_ALERTING:
		return "QMI_VOICE_CALL_STATE_ALERTING";
	case QMI_VOICE_CALL_STATE_HOLD:
		return "QMI_VOICE_CALL_STATE_HOLD";
	case QMI_VOICE_CALL_STATE_WAITING:
		return "QMI_VOICE_CALL_STATE_WAITING";
	case QMI_VOICE_CALL_STATE_DISCONNECTING:
		return "QMI_VOICE_CALL_STATE_DISCONNECTING";
	case QMI_VOICE_CALL_STATE_END:
		return "QMI_VOICE_CALL_STATE_END";
	case QMI_VOICE_CALL_STATE_SETUP:
		return "QMI_VOICE_CALL_STATE_SETUP";
	}
	return "QMI_CALL_STATE_<UNKNOWN>";
}

static bool qmi_to_ofono_status(uint8_t status, int *ret)
{
	int err = false;

	switch (status) {
	case QMI_VOICE_CALL_STATE_IDLE:
	case QMI_VOICE_CALL_STATE_END:
	case QMI_VOICE_CALL_STATE_DISCONNECTING:
		*ret = CALL_STATUS_DISCONNECTED;
		break;
	case QMI_VOICE_CALL_STATE_HOLD:
		*ret = CALL_STATUS_HELD;
		break;
	case QMI_VOICE_CALL_STATE_WAITING:
		*ret = CALL_STATUS_WAITING;
		break;
	case QMI_VOICE_CALL_STATE_ORIG:
		*ret = CALL_STATUS_DIALING;
		break;
	case QMI_VOICE_CALL_STATE_SETUP:
	case QMI_VOICE_CALL_STATE_INCOMING:
		*ret = CALL_STATUS_INCOMING;
		break;
	case QMI_VOICE_CALL_STATE_CONV:
		*ret = CALL_STATUS_ACTIVE;
		break;
	case QMI_VOICE_CALL_STATE_CC_IN_PROG:
		*ret = CALL_STATUS_DIALING;
		break;
	case QMI_VOICE_CALL_STATE_ALERTING:
		*ret = CALL_STATUS_ALERTING;
		break;
	default:
		err = true;
	}
	return err;
}

static enum call_direction qmi_to_ofono_direction(uint8_t qmi_direction)
{
	return qmi_direction - 1;
}

static void all_call_status_ind(struct qmi_result *result, void *user_data)
{
	struct ofono_voicecall *vc = user_data;

	int i;
	int offset;
	uint16_t len;
	bool status = true;
	int instance_size;
	const struct qmi_voice_call_information *call_information;
	const struct qmi_voice_remote_party_number *remote_party_number;
	const struct qmi_voice_remote_party_number_instance *remote_party_number_inst[16];
	struct l_queue *calls;

	static const uint8_t RESULT_CALL_STATUS_CALL_INFORMATION = 0x01;
	static const uint8_t RESULT_CALL_STATUS_REMOTE_NUMBER = 0x10;
	static const uint8_t RESULT_CALL_INFO_CALL_INFORMATION = 0x10;
	static const uint8_t RESULT_CALL_INFO_REMOTE_NUMBER = 0x11;

	DBG("");

	/* mandatory */
	call_information = qmi_result_get(
		result, RESULT_CALL_STATUS_CALL_INFORMATION, &len);

	if (!call_information) {
		call_information = qmi_result_get(
			result, RESULT_CALL_INFO_CALL_INFORMATION,
			&len);
		status = false;
	}

	if (!call_information || len < sizeof(call_information->size)) {
		DBG("Parsing of all call status indication failed");
		return;
	}

	if (!call_information->size) {
		DBG("No call informations received!");
		return;
	}

	if (len != call_information->size *
			sizeof(struct qmi_voice_call_information_instance) +
			sizeof(call_information->size)) {
		DBG("Call information size incorrect");
		return;
	}

	/* mandatory */
	remote_party_number = qmi_result_get(
		result,
		status ? RESULT_CALL_STATUS_REMOTE_NUMBER :
			 RESULT_CALL_INFO_REMOTE_NUMBER,
		&len);

	if (!remote_party_number) {
		DBG("Unable to retrieve remote numbers");
		return;
	}

	/* verify the length */
	if (len < sizeof(remote_party_number->size)) {
		DBG("Parsing of remote numbers failed");
		return;
	}

	/* expect we have valid fields for every call */
	if (call_information->size != remote_party_number->size) {
		DBG("Not all fields have the same size");
		return;
	}

	/* pull the remote call info into a local array */
	instance_size = sizeof(struct qmi_voice_remote_party_number_instance);

	for (i = 0, offset = sizeof(remote_party_number->size);
			offset < len && i < 16 && i < remote_party_number->size;
			i++) {
		const struct qmi_voice_remote_party_number_instance *instance;

		if (offset + instance_size > len) {
			DBG("Error parsing remote numbers");
			return;
		}

		instance = (void *)remote_party_number + offset;
		if (offset + instance_size + instance->number_size > len) {
			DBG("Error parsing remote numbers");
			return;
		}

		remote_party_number_inst[i] = instance;
		offset +=
			sizeof(struct qmi_voice_remote_party_number_instance) +
			instance->number_size;
	}

	calls = l_queue_new();

	for (i = 0; i < call_information->size && i < 16; i++) {
		struct ofono_call *call = l_new(struct ofono_call, 1);
		struct qmi_voice_call_information_instance call_info;
		const struct qmi_voice_remote_party_number_instance
			*remote_party = remote_party_number_inst[i];
		int number_size;
		char *tmp;

		call_info = call_information->instance[i];

		call->id = call_info.id;
		call->direction = qmi_to_ofono_direction(call_info.direction);
		call->type = 0; /* always voice */

		number_size = MIN(remote_party->number_size, OFONO_MAX_PHONE_NUMBER_LENGTH);
		tmp = l_strndup(remote_party->number, number_size);
		l_strlcpy(call->phone_number.number, tmp, sizeof(call->phone_number.number));
		l_free(tmp);

		if (strlen(call->phone_number.number) > 0)
			call->clip_validity = 0;
		else
			call->clip_validity = 2;

		if (qmi_to_ofono_status(call_info.state, &call->status)) {
			DBG("Ignore call id %d, because can not convert QMI state 0x%x to ofono.",
				call_info.id, call_info.state);
			l_free(call);
			continue;
		}

		DBG("Call %d in state %s(%d)", call_info.id,
			qmi_voice_call_state_name(call_info.state),
			call_info.state);

		l_queue_push_tail(calls, call);
	}

	ofono_call_list_notify(vc, calls);
}

static void dial_cb(struct qmi_result *result, void *user_data)
{
	struct cb_data *cbd = user_data;
	struct ofono_voicecall *vc = cbd->user;
	ofono_voicecall_cb_t cb = cbd->cb;
	uint16_t error;
	uint8_t call_id;

	static const uint8_t RESULT_CALL_ID = 0x10;

	DBG("");

	if (qmi_result_set_error(result, &error)) {
		DBG("QMI Error %d", error);
		CALLBACK_WITH_FAILURE(cb, cbd->data);
		return;
	}

	if (!qmi_result_get_uint8(result, RESULT_CALL_ID,
			&call_id)) {
		ofono_error("No call id in dial result");
		CALLBACK_WITH_FAILURE(cb, cbd->data);
		return;
	}

	DBG("New call QMI id %d", call_id);
	ofono_call_list_dial_callback(vc, call_id);

	CALLBACK_WITH_SUCCESS(cb, cbd->data);
}

static void dial(struct ofono_voicecall *vc,
			const struct ofono_phone_number *ph,
			enum ofono_clir_option clir, ofono_voicecall_cb_t cb,
			void *data)
{
	struct voicecall_data *vd = ofono_voicecall_get_data(vc);
	struct cb_data *cbd = cb_data_new(cb, data);
	struct qmi_param *param;
	const char *calling_number = phone_number_to_string(ph);

	static const uint8_t PARAM_CALL_NUMBER = 0x01;
	static const uint8_t PARAM_CALL_TYPE = 0x10;
	static const uint8_t QMI_VOICE_CALL_TYPE_VOICE = 0x00;

	DBG("");

	cbd->user = vc;
	memcpy(&vd->dialed, ph, sizeof(*ph));

	param = qmi_param_new();

	if (!qmi_param_append(param, PARAM_CALL_NUMBER,
			strlen(calling_number), calling_number))
		goto error;

	qmi_param_append_uint8(param, PARAM_CALL_TYPE,
				QMI_VOICE_CALL_TYPE_VOICE);

	if (qmi_service_send(vd->voice, QMI_VOICE_DIAL_CALL, param, dial_cb,
				cbd, l_free) > 0)
		return;

error:
	CALLBACK_WITH_FAILURE(cb, data);
	l_free(cbd);
	l_free(param);
}

static void answer_cb(struct qmi_result *result, void *user_data)
{
	struct cb_data *cbd = user_data;
	ofono_voicecall_cb_t cb = cbd->cb;
	uint16_t error;
	uint8_t call_id;

	static const uint8_t RESULT_CALL_ID = 0x10;

	DBG("");

	if (qmi_result_set_error(result, &error)) {
		DBG("QMI Error %d", error);
		CALLBACK_WITH_FAILURE(cb, cbd->data);
		return;
	}

	if (qmi_result_get_uint8(result, RESULT_CALL_ID, &call_id))
		DBG("Received answer result with call id %d", call_id);

	CALLBACK_WITH_SUCCESS(cb, cbd->data);
}

static void answer(struct ofono_voicecall *vc, ofono_voicecall_cb_t cb, void *data)
{
	struct voicecall_data *vd = ofono_voicecall_get_data(vc);
	struct cb_data *cbd;
	struct ofono_call *call;
	struct qmi_param *param = NULL;

	static const uint8_t PARAM_CALL_ID = 0x01;

	DBG("");

	call = l_queue_find(vd->call_list,
					ofono_call_match_by_status,
					L_UINT_TO_PTR(CALL_STATUS_INCOMING));

	param = qmi_param_new();
	cbd = cb_data_new(cb, data);
	cbd->user = vc;

	if (call == NULL) {
		ofono_error("Can not find a call to pick up");
		goto error;
	}

	if (!qmi_param_append_uint8(param, PARAM_CALL_ID,
			call->id))
		goto error;

	if (qmi_service_send(vd->voice, QMI_VOICE_ANSWER_CALL, param,
			answer_cb, cbd, l_free) > 0)
		return;

error:
	CALLBACK_WITH_FAILURE(cb, data);
	l_free(cbd);
	l_free(param);
}

static void end_call_cb(struct qmi_result *result, void *user_data)
{
	struct cb_data *cbd = user_data;
	ofono_voicecall_cb_t cb = cbd->cb;
	uint16_t error;
	uint8_t call_id;

	static const uint8_t RESULT_CALL_ID = 0x10;

	if (qmi_result_set_error(result, &error)) {
		DBG("QMI Error %d", error);
		CALLBACK_WITH_FAILURE(cb, cbd->data);
		return;
	}

	if (qmi_result_get_uint8(result, RESULT_CALL_ID, &call_id))
		DBG("Received end call result with call id %d", call_id);

	CALLBACK_WITH_SUCCESS(cb, cbd->data);
}

static void release_specific(struct ofono_voicecall *vc, int id,
			ofono_voicecall_cb_t cb, void *data)
{
	struct voicecall_data *vd = ofono_voicecall_get_data(vc);
	struct cb_data *cbd;
	struct qmi_param *param = NULL;

	static const uint8_t PARAM_CALL_ID = 0x01;

	DBG("");

	param = qmi_param_new();
	cbd = cb_data_new(cb, data);
	cbd->user = vc;

	if (!qmi_param_append_uint8(param, PARAM_CALL_ID, id))
		goto error;

	if (qmi_service_send(vd->voice, QMI_VOICE_END_CALL, param, end_call_cb,
			cbd, l_free) > 0)
		return;

error:
	CALLBACK_WITH_FAILURE(cb, data);
	l_free(cbd);
	l_free(param);
}

static void hangup_active(struct ofono_voicecall *vc, ofono_voicecall_cb_t cb,
				void *data)
{
	struct voicecall_data *vd = ofono_voicecall_get_data(vc);
	struct ofono_call *call;
	enum call_status active[] = {
		CALL_STATUS_ACTIVE,
		CALL_STATUS_DIALING,
		CALL_STATUS_ALERTING,
		CALL_STATUS_INCOMING,
	};

	DBG("");

	for (uint32_t i = 0; i < L_ARRAY_SIZE(active); i++) {
		call = l_queue_find(vd->call_list, ofono_call_match_by_status,
			L_INT_TO_PTR(active[i]));

		if (call)
			break;
	}

	if (call == NULL) {
		DBG("Can not find a call to hang up");
		CALLBACK_WITH_FAILURE(cb, data);
		return;
	}

	release_specific(vc, call->id, cb, data);
}

static void create_voice_cb(struct qmi_service *service, void *user_data)
{
	struct ofono_voicecall *vc = user_data;
	struct voicecall_data *data = ofono_voicecall_get_data(vc);

	DBG("");

	if (!service) {
		ofono_error("Failed to request Voice service");
		ofono_voicecall_remove(vc);
		return;
	}

	if (!qmi_service_get_version(service, &data->major, &data->minor)) {
		ofono_error("Failed to get Voice service version");
		ofono_voicecall_remove(vc);
		return;
	}

	data->voice = qmi_service_ref(service);

	qmi_service_register(data->voice, QMI_VOICE_ALL_CALL_STATUS_IND,
				all_call_status_ind, vc, NULL);

	ofono_voicecall_register(vc);
}

static int qmi_voicecall_probe(struct ofono_voicecall *vc,
					unsigned int vendor, void *user_data)
{
	struct qmi_device *device = user_data;
	struct voicecall_data *data;

	DBG("");

	data = l_new(struct voicecall_data, 1);
	data->call_list = l_queue_new();

	ofono_voicecall_set_data(vc, data);

	qmi_service_create(device, QMI_SERVICE_VOICE,
					create_voice_cb, vc, NULL);

	return 0;
}

static void qmi_voicecall_remove(struct ofono_voicecall *vc)
{
	struct voicecall_data *data = ofono_voicecall_get_data(vc);

	DBG("");

	ofono_voicecall_set_data(vc, NULL);

	qmi_service_unregister_all(data->voice);

	qmi_service_unref(data->voice);

	l_queue_destroy(data->call_list, l_free);
	l_free(data);
}

static const struct ofono_voicecall_driver driver = {
	.probe		= qmi_voicecall_probe,
	.remove		= qmi_voicecall_remove,
	.dial		= dial,
	.answer		= answer,
	.hangup_active  = hangup_active,
	.release_specific  = release_specific,
};

OFONO_ATOM_DRIVER_BUILTIN(voicecall, qmimodem, &driver)

