#!/usr/bin/env python3
# Eryn Wells <eryn@erynwells.me>

'''
New script.
'''


import argparse
import datetime
import os
import os.path
import shutil
import subprocess
from PIL import Image
from PIL.ExifTags import TAGS
from typing import Optional
from website.metadata import slugify


PHOTOS_CONTENT_DIR = 'content/photos'


def parse_args(argv, *a, **kw):
    parser = argparse.ArgumentParser(*a, **kw)
    parser.add_argument('-e', '--edit', action='store_true')
    parser.add_argument('-n', '--dry-run', action='store_true')
    parser.add_argument('-t', '--title')
    parser.add_argument('-s', '--slug')
    parser.add_argument('--dump-exif', action='store_true')
    parser.add_argument('photos', nargs='+')
    args = parser.parse_args(argv)
    return args


def main(argv):
    args = parse_args(argv[1:], prog=argv[0])

    earliest_exif_date: Optional[datetime.datetime] = None

    for index, photo in enumerate(args.photos):
        print(f'image\t\t{photo}')

        try:
            image = Image.open(photo)
        except IOError:
            continue

        raw_exif = image._getexif()
        friendly_exif = {TAGS[k]: v for k, v in raw_exif.items() if k in TAGS}

        try:
            date_string = f'{friendly_exif["DateTime"]} {friendly_exif["OffsetTime"]}'
            exif_date = datetime.datetime.strptime(date_string, '%Y:%m:%d %H:%M:%S %z')
        except KeyError:
            exif_date = datetime.datetime.strptime(friendly_exif["DateTime"], '%Y:%m:%d %H:%M:%S')
        print(f'capture-time\t{exif_date.isoformat()}')

        iso_rating = friendly_exif.get('ISOSpeedRatings')
        if iso_rating:
            print(f'iso\t\t{iso_rating}')

        focal_length_35mm = friendly_exif.get('FocalLengthIn35mmFilm')
        focal_length = friendly_exif.get('FocalLength')
        if focal_length or focal_length_35mm:
            print(f'focal-length\t{focal_length} {focal_length_35mm}')

        fstop = friendly_exif.get('FNumber')
        if fstop:
            print(f'f-stop\t\t{fstop}')

        exposure_time = friendly_exif.get('ExposureTime')
        if exposure_time:
            print(f'exposure-time\t{exposure_time}')

        if not earliest_exif_date or exif_date < earliest_exif_date:
            earliest_exif_date = exif_date

        if index < len(args.photos) - 1:
            print()

    if not earliest_exif_date:
        earliest_exif_date = datetime.datetime.now()

    year = earliest_exif_date.year
    month = earliest_exif_date.month

    if args.slug:
        name = args.slug
    elif args.title:
        name = slugify(args.title)
    else:
        name = os.path.splitext(os.path.basename(photo))[0]

    post_path_year = os.path.join(PHOTOS_CONTENT_DIR, f'{year:04}', name)
    post_path_year_month = os.path.join(PHOTOS_CONTENT_DIR, f'{year:04}', f'{month:02}', name)

    if os.path.exists(post_path_year):
        if os.path.exists(post_path_year_month):
            print("Couldn't find path for photo post. Both of the following paths exist.", file=sys.stderr)
            print(f'  {post_path_year}', file=sys.stderr)
            print(f'  {post_path_year_month}', file=sys.stderr)
            return -1
        else:
            post_path = post_path_year_month
    else:
        post_path = post_path_year

    try:
        hugo_command = ['hugo', 'new', '--clock', earliest_exif_date.isoformat(), post_path]
        if not args.dry_run:
            result = subprocess.run(hugo_command)
            result.check_returncode()
        else:
            print(' '.join(hugo_command), file=sys.stderr)
    except subprocess.CalledProcessError:
        print(f'Failed to create new Hugo post', file=sys.stderr)
        return -1

    index_file_path = os.path.join(post_path, 'index.md')

    if args.title and not args.dry_run:
        # The hugo command can't set a title for a post so I need to do it myself.
        with open(index_file_path) as index_file:
            index_file_contents = index_file.readlines()

        for i in range(len(index_file_contents)):
            line = index_file_contents[i]

            if not line.startswith('title:'):
                continue

            updated_line = f'title: "{args.title}"\n'
            index_file_contents[i] = updated_line

        with open(index_file_path, 'w') as index_file:
            index_file.writelines(index_file_contents)

    if not args.dry_run and args.edit:
        editor = os.environ.get('EDITOR', 'vi')
        subprocess.run([editor, index_file_path], shell=True)

    for photo in args.photos:
        print(f'Copy {photo} -> {post_path}')
        try:
            if not args.dry_run:
                shutil.copy(photo, post_path)
        except IOError:
            print(f'Failed to copy {photo}', file=sys.stderr)
            return -2


if __name__ == '__main__':
    import sys
    result = main(sys.argv)
    sys.exit(0 if not result else result)
