#! /usr/bin/env python3

import sys
import argparse
import tempfile
import os
import shutil

import yaml

import postcard
from postcard import preview
from postcard.page import Page
from postcard.remote import rsync
from postcard import sections

plugins = [sections.Image, sections.Gallery, sections.Title, sections.SubTitle, sections.Text, sections.TextFile, sections.Files, sections.Sources, sections.Videos, sections.Signature, sections.Map, sections.MapTrack]

class Cancelled(Exception):
    pass

# Like a simple list, but this class supports adding custom attributes
class Items(list):
    pass

def parser_action(Section):
    class Action(argparse.Action):
        def __call__(self, parser, namespace, values, option_string=None):
            if values is None:
                values = []
            if type(values) is not list:
                values = [values]
            
            section = Section(*values)
            namespace.append(section)
            
            return None
    
    return Action

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Postcard -- Souvenirs over Web', prog="postcard")
    parser.add_argument("-c", "--config",
                        dest="config",
                        default=os.path.expanduser("~/.config/postcard/config.yml"),
                        help="Configuration file")
    parser.add_argument('--no-preview',
                        dest='preview',
                        action='store_false',
                        default=True,
                        help="Disable preview before uploading")
    parser.add_argument('--dry-run', "-n",
                        dest='dryrun',
                        action='store_true',
                        default=False,
                        help="Stop before uploading")
    parser.add_argument('--expire', "-e",
                        dest='expire',
                        type=int,
                        default=90,
                        help="Days before expiration")
    parser.add_argument('--version', "-v",
                        action='version',
                        version="%(prog)s " + postcard.__version__)
    # parser.add_argument('--archive', "-a",
    #                     dest='archive',
    #                     action='store_true',
    #                     default=False,
    #                     help="Archive a copy of the postcard")
    parser.add_argument('--keep', "-k",
                        dest='keep',
                        action='store_true',
                        default=False,
                        help="Keep temporary files")
    
    for item in plugins:
        parser.add_argument("--" + item.name,
                            nargs=item.nargs,
                            action=parser_action(item),
                            help=item.help,
                            metavar=item.metavar,
        )
    
    args = parser.parse_args(namespace=Items())
    sections = list(args)
    
    with open(args.config) as f:
        config = yaml.load(f)
    
    if len(args) == 0:
        print("No section provided on the command line.")
        print("Ok, if you don't want to publish anything, that's fine!")
        sys.exit(0)
    
    page = Page(sections, args.expire)
    try:
        targetdir = tempfile.mkdtemp(prefix="postcard_")
        os.chdir(targetdir)
        os.mkdir(page.uuid)
        
        page.prepare(config.get("sections", {}))
        page.summary(sys.stdout)
        with open(os.path.join(page.uuid, "index.html"), "w") as f:
            page.html(f)
        
        for attachment in page.attachments():
            shutil.copy(attachment[1], os.path.join(page.uuid, attachment[0]))
        if args.preview:
            if not preview.run(page, 3000):
                raise Cancelled
        
        with open(os.path.join(page.uuid, "EXPIRE"), "w") as f:
            print(page.expire.strftime("%s"), file=f)
        
        if not args.dryrun:
            url = rsync(config['remote'], page)
            print("Postcard availabe at {url}".format(url=url))
    
    except Cancelled:
        pass
    
    if args.keep:
        print("Temporary files kept in %s" % targetdir)
    else:
        shutil.rmtree(targetdir)

