#!/usr/bin/env python
#-*- coding: utf-8 -*-
"""
YASGG - Yet another static gallery generator. CLI.

Usage: yasggctl build -n <album-name> -i <photos-import-dir> [-t <theme>] [-p <password>] [-r <recrusive>]
       yasggctl serve [-o <port>] [-b <bind>]
       yasggctl [-h] [-v]


Build command:
  Creates a new album in the current working directory.
  Example: yasggctl build --recrusive 1 --photos-import-dir ./tests/sample --album-name "foo bar" --theme default

  -n <ablum-name>, --album-name <album-name>                        Name of the new album.
  -i <photos-import-dir>, --photos-import-dir <photos-import-dir>   Directory of photos to import.
  -p <password>, --password <password>                              Use encryption of images. Use a _STRONG_ password!
  -r {0,1}, --recrusive                                             Search recrusive for photos into --photos-import-dir [default: 0]
  -t {default, galleria_classic}, --theme                           The theme to use. [default: default]


Serve command:
  Serves a created album.
  Example: yasggctl serve -o 9000 -b 0.0.0.0

  -o <port>, --port <port>                                          Name of the new album. [default: 9000]
  -b <bind>, --bind <bind>                                          Address to run the test server on [default: 127.0.0.1]


Global options:
  -h, --help                                                        Show this help message and exit.
  -v, --version                                                     Show program's version number and exit.
"""
import codecs
import os
from shutil import copytree
import sys
import time

from docopt import docopt
from jinja2 import Template
import SimpleHTTPServer
import webbrowser

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + os.sep + '..' + os.sep + '..' + os.sep)


from yasgg import get_version
from yasgg import logger
from yasgg.settings import IMAGE_FILE_EXTENSIONS_2_IMPORT
from yasgg.utils import walkdir
from yasgg.models import Photo, Album, Theme
from yasgg.server import ThreadingSimpleServer


class Commands(object):
    def __init__(self, args):
        if args['build']:
            self.build(args)
        elif args['serve']:
            self.serve(args)

    def build(self, args):
        use_encryption = bool(args['--password'])
        if (use_encryption and len(args['--password']) < 8):
            logger.error('Password is too short. Use min 8 characters.')
            return

        album_basedir = os.path.abspath('.%s%s' % (os.sep, args['--album-name'].lower().replace(' ', '_'))) + os.sep
        if os.path.exists(album_basedir):
            logger.error('The album %s already exists!' % (album_basedir))
            return

        if not os.path.exists(args['--photos-import-dir']):
            logger.error('The photos dir %s does not exist!' % (args['--photos-import-dir']))
            return

        theme = Theme(args['--theme'])
        template = Template(codecs.open(theme.template, 'r', 'utf8').read())

        # copy theme data
        copytree(theme.basedir, album_basedir)

        # copy asset data neededfor all themes
        assets_dir_for_all = '%s%s' % (os.path.join(theme.basedir, '..', '_assets_for_all_themes'), os.sep)
        copytree(assets_dir_for_all, '%s%s' % (album_basedir, '_assets_for_all_themes'))

        album = Album(basedir=album_basedir, password=args['--password'])

        # import photos
        logger.info('Searching for photos in %s' % (args['--photos-import-dir']))
        photos = {}
        exif_date_for_all_photos = True
        for photo_2_import in walkdir(dir_2_walk=args['--photos-import-dir'], recrusive=int(args['--recrusive'])):
            extension = os.path.splitext(photo_2_import)[1][1:]
            if extension.lower() not in IMAGE_FILE_EXTENSIONS_2_IMPORT:
                continue
            photo = Photo(image_file_original=photo_2_import, album=album)
            exif_date = photo.exif_date
            if exif_date:
                photos[exif_date + photo_2_import] = photo_2_import
            else:
                exif_date_for_all_photos = False
                photos[photo_2_import] = photo_2_import


        # if there is not an exif date on all photos, use path instead
        if not exif_date_for_all_photos:
            for photo_key, photo_file in photos.items():
                photos[photo_file] = photo_file
                del photos[photo_key]

        photos_for_tpl = []
        for photo_key in sorted(photos.iterkeys()):
            logger.debug('Processing %s' % (photo_2_import))
            photo_2_import = photos[photo_key]
            photo = Photo(image_file_original=photo_2_import, album=album)

            # create thumbnail and main image
            thumbnail_data = photo.create_thumbnail()
            image_file_data = photo.provide()

            # make photo path relative
            thumbnail_data['thumbnail_file'] = os.sep.join(thumbnail_data['thumbnail_file'].split(os.sep)[-2:])
            image_file_data['file'] = os.sep.join(image_file_data['file'].split(os.sep)[-2:])

            # merge two data dicts into one
            tpl_photo_data = dict(thumbnail_data.items() + image_file_data.items())

            photos_for_tpl.append(tpl_photo_data)
            # write html file
        with open(album.html_file, 'wb') as html_file:
            logger.info('Writing html file %s' % (album.html_file))
            html = template.render(photos=photos_for_tpl, password=args['--password'], album_name=args['--album-name'],
                                   timestamp=int(time.time()))
            html_file.write(html.encode('utf-8'))

    def serve(self, args):
        server = ThreadingSimpleServer((args['--bind'], int(args['--port'])), SimpleHTTPServer.SimpleHTTPRequestHandler)
        browser_host = args['--bind']
        if args['--bind'] == '0.0.0.0':
            browser_host = '127.0.0.1'
        webbrowser.open_new_tab('http://%s:%s/' % (browser_host, args['--port']))
        try:
            while 1:
                sys.stdout.flush()
                server.handle_request()
        except KeyboardInterrupt:
            pass

args = docopt(__doc__, sys.argv[1:], version=get_version())
Commands(args)