/*
 * Copyright (c) 2026 Meshtastic LLC
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * 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, see <https://www.gnu.org/licenses/>.
 */
@file:Suppress("MatchingDeclarationName", "LongMethod", "CyclomaticComplexMethod", "MaxLineLength")

package org.meshtastic.core.takserver

import kotlin.time.Instant

fun CoTMessage.toXml(): String = buildString {
    append(
        "<?xml version='1.0' encoding='UTF-8' standalone='yes'?><event version='2.0' uid='${uid.xmlEscaped()}' type='$type' time='${time.toXmlString()}' start='${start.toXmlString()}' stale='${stale.toXmlString()}' how='$how'><point lat='$latitude' lon='$longitude' hae='$hae' ce='$ce' le='$le'/><detail>",
    )

    contact?.let {
        append(
            "<contact endpoint='${it.endpoint ?: DEFAULT_TAK_ENDPOINT}' callsign='${it.callsign.xmlEscaped()}'/><uid Droid='${it.callsign.xmlEscaped()}'/>",
        )
    }

    group?.let { append("<__group role='${it.role.xmlEscaped()}' name='${it.name.xmlEscaped()}'/>") }

    status?.let { append("<status battery='${it.battery}'/>") }

    track?.let { append("<track course='${it.course}' speed='${it.speed}'/>") }

    if (chat != null) {
        val senderUid = uid.geoChatSenderUid()
        val messageId = uid.geoChatMessageId()
        append(
            "<__chat parent='RootContactGroup' groupOwner='false' messageId='$messageId' chatroom='${chat.chatroom.xmlEscaped()}' id='${chat.chatroom.xmlEscaped()}' senderCallsign='${chat.senderCallsign?.xmlEscaped() ?: ""}'><chatgrp uid0='${senderUid.xmlEscaped()}' uid1='${chat.chatroom.xmlEscaped()}' id='${chat.chatroom.xmlEscaped()}'/></__chat>",
        )
        append("<link uid='${senderUid.xmlEscaped()}' type='a-f-G-U-C' relation='p-p'/>")
        append("<__serverdestination destinations='0.0.0.0:4242:tcp:${senderUid.xmlEscaped()}'/>")
        append(
            "<remarks source='BAO.F.ATAK.${senderUid.xmlEscaped()}' to='${chat.chatroom.xmlEscaped()}' time='${time.toXmlString()}'>${chat.message.xmlEscaped()}</remarks>",
        )
    } else if (!remarks.isNullOrEmpty()) {
        append("<remarks>${remarks.xmlEscaped()}</remarks>")
    }

    rawDetailXml?.takeIf { it.isNotEmpty() }?.let { append(it) }

    append("</detail></event>")
}

private fun Instant.toXmlString(): String = this.toString()
