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

import argparse
import datetime
import os
import os.path as osp
import shutil
import subprocess
from PIL import Image
from PIL.ExifTags import TAGS
from typing import Optional
from erynwells_me.metadata import slugify
from erynwells_me.paths import content_path


PHOTOS_CONTENT_DIR = osp.join(content_path(), '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 = osp.splitext(osp.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)
