#!/usr/bin/python

# SPDX-FileCopyrightText: 2025 Schimon Jehudah <https://schapps.woodpeckersnest.eu>
#
# SPDX-License-Identifier: MIT

# -*- coding: utf-8 -*-

import datetime
import os
from slixmpp.stanza.iq import Iq
import sys
import xml.etree.ElementTree as ET

#logger = UtilityLogger(__name__)

XMLNS_FOAF = "{http://xmlns.com/foaf/0.1/}"
XMLNS_DOAP = "{http://usefulinc.com/ns/doap#}"
XMLNS_RDF = "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}"
XMLNS_SCHEMA = "{https://schema.org/}"
XMLNS_XMPP_DOAP = "{https://linkmauve.fr/ns/xmpp-doap#}"

__version__  = "0.1"

class Doap:

    def parse(filename: str):
        properties = {}
        tree = ET.parse(filename)
        root = tree.getroot()
        # Project
        #project = tree.find(f"{XMLNS_DOAP}Project")
        project = root.find(f"{XMLNS_DOAP}Project")
        created = project.find(f"{XMLNS_DOAP}created")
        properties["created"] = created.text if created is not None else ""
        description = project.find(f"{XMLNS_DOAP}description")
        properties["description"] = description.text if description is not None else ""
        homepage = project.find(f"{XMLNS_DOAP}homepage")
        properties["homepage"] = homepage.text if homepage is not None else ""
        logo = project.find(f"{XMLNS_SCHEMA}logo")
        properties["logo"] = logo.attrib[f"{XMLNS_RDF}resource"] if logo is not None else ""
        name = project.find(f"{XMLNS_DOAP}name")
        properties["name"] = name.text if name is not None else ""
        properties["os"] = []
        for i in project.findall(f"{XMLNS_DOAP}os"):
            properties["os"].append(i.text)
        properties["programming-language"] = []
        for i in project.findall(f"{XMLNS_DOAP}programming-language"):
            properties["programming-language"].append(i.text)
        short_name = project.find(f"{XMLNS_DOAP}short-name")
        properties["short-name"] = short_name.text if short_name is not None else properties["name"].lower()
        shortdesc = project.find(f"{XMLNS_DOAP}shortdesc")
        properties["shortdesc"] = shortdesc.text if shortdesc is not None else ""
        support_forum = project.find(f"{XMLNS_DOAP}support-forum")
        properties["support-forum"] = support_forum.attrib[f"{XMLNS_RDF}resource"] if support_forum is not None else ""
        # Maintainer
        properties["maintainer"] = {}
        properties["maintainer"]["email"] = ""
        properties["maintainer"]["name"] = name
        properties["maintainer"]["uri"] = homepage
        maintainer = project.find(f"{XMLNS_DOAP}maintainer")
        if maintainer is not None:
            person = maintainer.find(f"{XMLNS_FOAF}Person")
            if person is not None:
                maintainer_homepage = person.find(f"{XMLNS_FOAF}homepage")
                properties["maintainer"]["uri"] = maintainer_homepage.attrib[
                        f"{XMLNS_RDF}resource"] if maintainer_homepage is not None else ""
                maintainer_name = person.find(f"{XMLNS_FOAF}name")
                properties["maintainer"]["name"] = maintainer_name.text if maintainer_name is not None else ""
        # Release
        properties["version"] = {}
        properties["version"]["created"] = ""
        properties["version"]["revision"] = ""
        release = project.find(f"{XMLNS_DOAP}release")
        if release is not None:
            version = release.find(f"{XMLNS_DOAP}Version")
            if version is not None:
                version_created = version.find(f"{XMLNS_DOAP}created")
                properties["version"]["created"] = version_created.text if version_created is not None else ""
                version_revision = version.find(f"{XMLNS_DOAP}revision")
                properties["version"]["revision"] = version_revision.text if version_revision is not None else ""
        return properties

class Atom:

    def generate(atom: dict, link=None):
        """Generate an Atom Syndication Format (RFC 4287)."""
        # link = XmppUtilities.form_a_node_link(pubsub, node)
        # subtitle = "XMPP PubSub Syndication Feed"
        description = ("This is a syndication feed generated with Schapps.")
        e_feed = ET.Element("feed")
        e_feed.set("xmlns", "http://www.w3.org/2005/Atom")
        ET.SubElement(e_feed, "icon").text = atom["icon"]
        ET.SubElement(e_feed, "logo").text = atom["logo"]
        ET.SubElement(e_feed, "title", {
            "type": "text"}).text = atom["title"]
        ET.SubElement(e_feed, "subtitle", {
            "type": "text"}).text = atom["subtitle"]
        for link in atom["links"]:
            ET.SubElement(e_feed, "link", {
                "type": link["type"],
                "rel": link["rel"],
                "href": link["href"]})
        ET.SubElement(e_feed, "generator", {
            # "uri": "gemini://schapps.i2p",
            "uri": "https://schapps.woodpeckersnest.eu",
            "version": f"{__version__}"}).text = "Schapps"
        time_now = datetime.datetime.now(datetime.UTC).isoformat()
        ET.SubElement(e_feed, "updated").text = time_now
        for item in atom["items"]:
            e_entry = ET.SubElement(e_feed, "entry")
            ET.SubElement(e_entry, "title").text = item["title"]
            links = item["links"] if "links" in item else None
            if links:
                for link in links:
                    if link["href"]:
                        ET.SubElement(e_entry, "link", {
                            "href" : link["href"],
                            "rel"  : link["rel"],
                            "type" : link["type"]})
            content = item["content"] if "content" in item else None
            if content:
                ET.SubElement(e_entry, "content", {
                    "type": "text"}).text = content
            else:
                ET.SubElement(e_entry, "content").text = ""
            summary = item["summary"]
            if summary:
                summaryd = {
                    "type" : "text",
                    "text" : item["summary"]}
                ET.SubElement(e_entry, "summary", {
                    "type": summaryd["type"]}).text = summaryd["text"]
            else:
                ET.SubElement(e_entry, "summary").text = ""
            for date in ("published", "updated"):
                date_string = item[date]
                if date_string:
                    date_object = datetime.datetime.strptime(
                        date_string, "%Y-%m-%d").isoformat()
                    ET.SubElement(e_entry, date).text = date_object
            authors = item["authors"] if "authors" in item else None
            if authors:
                for author in authors:
                    e_author = ET.SubElement(e_entry, "author")
                    if author["email"]:
                        ET.SubElement(e_author, "email").text = author["email"]
                    if author["uri"] is not None:
                        ET.SubElement(e_author, "uri").text = author["uri"]
                    ET.SubElement(e_author, "name").text = author["name"]
            categories = item["categories"]
            if categories:
                for category in categories:
                    ET.SubElement(e_entry, "category", {"term": category})

            ET.SubElement(e_entry, "id").text = item["id"]
        return ET.tostring(e_feed, encoding="unicode")

class Publish:

    def content() -> None:
        # Generate Atom
        #link = "/"
        atom = {}
        atom["items"] = []
        atom["icon"] = "icon.svg"
        atom["image"] = "image.svg"
        atom["logo"] = "logo.svg"
        atom["title"] = "Chat Happy"
        atom["subtitle"] = "Online. Worry-free. Upgrade your messenger today!"
        atom["language"] = "en"
        atom["links"] = []
        for filename in os.listdir("doap"):
            properties = Doap.parse(f"doap/{filename}")
            atom_item = {}
            atom_item["title"] = properties["name"]
            atom_item["links"] = [
                {"href" : properties["homepage"],
                 "rel" : "alternate",
                 "type" : "text/html"},
                {"href" : properties["support-forum"],
                 "rel" : "alternate",
                 "type" : "x-scheme-handler/xmpp"},
                # TODO Cache graphics file and check its mime-type.
                {"href" : properties["logo"],
                 "rel" : "enclosure",
                 "type" : "application/octet-stream"}
            ]
            atom_item["summary"] = properties["shortdesc"]
            atom_item["content"] = properties["description"]
            atom_item["published"] = properties["created"]
            atom_item["updated"] = properties["version"]["created"]
            #properties["maintainer"]["uri"] = filename
            atom_item["authors"] = [properties["maintainer"]]
            atom_item["categories"] = properties["os"] + properties["programming-language"]
            atom_item["id"] = properties["homepage"] #properties["short-name"]
            atom["items"].append(atom_item)
        atom_as_string = Atom.generate(atom)
        filename_atom = "chathappy.atom"
        with open(filename_atom, "w") as fn:
            fn.write(atom_as_string)

if __name__ == "__main__":

    Publish.content()
