#!/usr/bin/env raku
use v6.e.PREVIEW;

use DB;
use DB::BlogMeta;
use DB::MarkdownPost;
use DB::IdrisPost;

my %*SUB-MAIN-OPTS =
    :named-anywhere,
    :bundling,
;

#| The directory this script is located in
my IO::Path:D $default-blog-dir = $*PROGRAM.parent;

#| Default database directory
my IO::Path:D $default-db-dir =
    do if %*ENV<BLOG_TEST> {
        $default-blog-dir.add('test-db/')
    } else {
        $default-blog-dir.add('db/')
    };

#| The default output directory
my IO::Path:D $default-site-dir = $default-blog-dir.add('site/');

#| The default idris ipkg
my IO::Path:D $default-ipkg = $default-blog-dir.add('projects/Idris/Idris.ipkg');

#| Initalize the database
multi MAIN(
    "db",
    "init",
    #| The path of the database file
    IO::Path(Str) :$db-dir = $default-db-dir,
    #| Overwrite an already existing database file
    Bool :$force
) {
    die "Database folder already exists, use --force to overwrite: {$db-dir.Str}"
    if $db-dir.e && !$force;

    print "Blog Title: ";
    my $title = get;
    print "Tagline: ";
    my $tagline = get;

    my $meta = BlogMeta.new: title => $title, tagline => $tagline;

    my $db = DB::PostDB.init: $meta;

    $db.write: $db-dir;
}

#| Ensure that the database loads, erroring otherwise
multi MAIN(
    "db",
    "verify",
    #| The path of the database file
    IO::Path(Str) :$db-dir = $default-db-dir,
) {
    read-db $db-dir;
    say "Database OK";
}

#| Create a new markdown post
multi MAIN(
    "new",
    "markdown",
    #| The path to the markdown file
    IO::Path(Str) $source,
    #| The path of the database file
    IO::Path(Str) :$db-dir = $default-db-dir,
    #| The date/time the post should be recorded as posted at
    DateTime(Str) :$posted-at = DateTime.now,
    #| Should the post be hidden from the archive?
    Bool :$hidden = False,
) {
    my $db = read-db $db-dir;
    my $id =
        $db.insert-post:
        MarkdownPost.new(
            source => $source.absolute.IO,
            posted-at => $posted-at,
            hidden => $hidden,
        );
    $db.write: $db-dir;
    say 'Post inserted with id ', $id;
    say 'Post has slugs: ', $db.posts{$id}.all-slugs;
}

#| Create a new idris post
multi MAIN(
    "new",
    "idris",
    #| The path to the idris file
    IO::Path(Str) $source,
    #| The path to the ipkg file
    IO::Path(Str) :$ipkg = $default-ipkg,
    #| The path of the database file
    IO::Path(Str) :$db-dir = $default-db-dir,
    #| The date/time the post should be recorded as posted at
    DateTime(Str) :$posted-at = DateTime.now,
    #| Should the post be hidden from the archive?
    Bool :$hidden = False,
) {
    say $default-ipkg;
    my $db = read-db $db-dir;
    my $id =
        $db.insert-post:
        IdrisPost.new(
            source => $source.absolute.IO,
            posted-at => $posted-at,
            hidden => $hidden,
            ipkg => $ipkg.absolute.IO,
        );
    $db.write: $db-dir;
    say 'Post inserted with id ', $id;
    say 'Post has slugs: ', $db.posts{$id}.all-slugs;
}

#| Render the blog to html
multi MAIN(
   "render",
    #| The path of the database directory
    IO::Path(Str) :$db-dir = $default-db-dir,
    #| The path of the output directory
    IO::Path(Str) :$site-dir = $default-site-dir,
) {
    my $db = read-db $db-dir;
    $db.render: $site-dir;
}