#!/usr/bin/env python3

# Libervia ActivityPub Gateway
# Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero 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 Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from typing import cast
from twisted.words.protocols.jabber import jid
from wokkel import data_form

from libervia.backend.core.constants import Const as C
from libervia.backend.core.core_types import SatXMPPEntity
from libervia.backend.core.i18n import D_, _
from libervia.backend.core.log import getLogger
from libervia.backend.plugins.plugin_xep_0004 import DataForm, Text
from libervia.backend.plugins.plugin_xep_0050 import (
    XEP_0050,
    AdHocCallbackData,
    AdHocCommand,
    AdHocError,
    Error,
    Note,
    NoteType,
    PageData,
    Status,
)


log = getLogger(__name__)
NS_XMPP_JID_NODE_2_AP = "https://libervia.org/ap_gateway/xmpp_jid_node_2_ap_actor"


class APAdHocService:
    """Ad-Hoc commands for AP Gateway"""

    def __init__(self, apg):
        self.host = apg.host
        self.apg = apg
        self._c = cast(XEP_0050, self.host.plugins["XEP-0050"])

    def init(self, client: SatXMPPEntity) -> None:
        self._c.register_ad_hoc_command(
            client,
            AdHocCommand(
                callback=self.xmpp_jid_node_2_ap_actor,
                label=D_("Convert XMPP JID/Node to AP actor"),
                node=NS_XMPP_JID_NODE_2_AP,
                allowed_magics=[C.ENTITY_ALL],
                form=DataForm(
                    title=D_("XMPP JID/node to AP actor conversion"),
                    namespace=NS_XMPP_JID_NODE_2_AP,
                    fields=[Text(var="jid", required=True), Text(var="node")],
                ),
            ),
        )

    async def xmpp_jid_node_2_ap_actor(
        self,
        client: SatXMPPEntity,
        page_data: PageData,
    ) -> AdHocCallbackData:
        """Convert XMPP JID/Node to AP actor.

        @param page_data: Ad-Hoc page data.
        @return: Command results.
        @raise AdHocError: When the JID is invalid or when no actor is found.
        """
        jid_s = page_data.form.get_field("jid", Text).value
        if not jid_s:
            raise AdHocError(Error.BAD_PAYLOAD, text=f'Invalid "jid": {jid_s!r}.')
        xmpp_jid = jid.JID(jid_s)
        xmpp_node = page_data.form.get_field("node", Text).value
        actor = await self.apg.get_ap_account_from_jid_and_node(xmpp_jid, xmpp_node)
        return AdHocCallbackData(status=Status.COMPLETED, notes=[Note(text=actor)])
