use v6.e.PREVIEW;

#| Post database
unit module DB;

use Pandoc;
use JSON::Class:auth<zef:vrurg>;

use DB::Post;
use DB::BlogMeta;
use DB::MarkdownPost;
use DB::IdrisPost;
use DB::PlaceholderPost;

class Posts is json(
    :dictionary(
        :keyof(Int:D),
        MarkdownPost:D,
        IdrisPost:D,
        PlaceholderPost:D,
    )) {}

subset PostTypes where MarkdownPost:D | IdrisPost:D | PlaceholderPost:D;

#| The top level posts database
class PostDB is json(:pretty) {
   #| The metadat for the blog
   has BlogMeta:D $.meta is required;
   #| A mapping from post ids to posts
   has %.posts is Posts;
   #| The post id to use for placeholder posts
   has Int $.placeholder-id = 0;

   method TWEAK() {
       %!posts := Posts.new unless %!posts;
   }

   #| Get the next unused post ID
   method next-post-id(--> Int) {
       if %!posts.elems > 0 {
           %!posts.keys.max + 1
       } else {
           0
       }
   }

   #| Insert a new post to the DB, returning its id
   method insert-post(PostTypes $post --> Int) {
       my $id = self.next-post-id;
       %!posts{$id} = $post;
       $id
   }

   #| Initialize a new database
   method init(BlogMeta:D $meta --> PostDB:D) {
       my %posts is Posts = Posts.new;
       %posts{0} = PlaceholderPost.empty;
       PostDB.new(
           meta => $meta,
           posts => %posts,
       )
   }
}