use v6.e.PREVIEW;

use DB::Post;
use DB::BlogMeta;

use XML;

unit module Atom;

# get the link for a post
sub post-link(BlogMeta:D $meta, Int:D $id, Post:D $post --> Str:D) {
    my @slugs = $post.all-slugs;
    my $base = $meta.get-base-url;
    if @slugs.elems {
       "$base/posts/by-slug/{@slugs[*-1]}.html"
    } else {
       "$base/posts/by-id/$id.html"
    }
}

#| Convert a single post to an atom item
sub post-to-item(BlogMeta:D $meta, Int:D $id, Post:D $post --> XML::Element) {
    my $link = post-link $meta, $id, $post;
    my $desc = $post.description;
    my $xml = XML::Element.new(:name<entry>);
    $xml.append:
        XML::Element.new(:name<id>, :nodes([$link]));
    $xml.append:
        XML::Element.new(:name<title>, :nodes([$post.title]));
    $xml.append:
        XML::Element.new(:name<updated>, :nodes([$post.updated]));
    $xml.append:
        XML::Element.new(:name<published>, :nodes([$post.posted-at]));
    my $author = XML::Element.new(:name<author>);
    $author.append:
        XML::Element.new(:name<email>, :nodes(["thatonelutenist@stranger.systems"]));
    $author.append:
        XML::Element.new(:name<name>, :nodes(["Nathan McCarty"]));
    $xml.append: $author;
    $xml.append:
        XML::Element.new(:name<link>, :attribs({:href($link), :rel<alternate>}));
    # TODO: Actually embed the content
    $xml.append:
        XML::Element.new(:name<content>, :attribs({:src($link), :type<html>}));
    $xml.append:
        XML::Element.new(:name<summary>, :nodes([$desc])) if $desc;
    if $post.tags {
        for $post.tags -> $tag {
            $xml.append:
                XML::Element.new(:name<category>, :attribs({:term($tag)}));
        }
    }

    $xml
}

#| Produce an atom feed from the database
sub posts-to-atom($db --> XML::Element) is export {
    my $updated = $db.posts.values.map(*.updated).max;
    my $xml =
        XML::Element.new(
            :name<feed>,
            :attribs({:xmlns('http://www.w3.org/2005/Atom')}));
    $xml.append: XML::Element.new(:name<id>, :nodes([$db.meta.get-base-url]));
    $xml.append: XML::Element.new(:name<title>, :nodes([$db.meta.title]));
    $xml.append: XML::Element.new(:name<updated>, :nodes([$updated]));
    for $db.sorted-posts -> $pair {
        unless $pair.value.hidden {
            $xml.append: post-to-item $db.meta, $pair.key, $pair.value;
        }
    }
    $xml
}