#!/usr/bin/env python

"""
Create the media object
"""
import os
from datetime import datetime
import ffmpeg
import sys

#Local Imports
from hashing import xx_hash, hash_path
from get_image_tag import get_image_date
# from configure import files
from lumberjack import timber

log = timber(__name__)

class Media:
    """ media class """

    def __init__(self, source_path,event,config):
        """ init """

        self.configuration = config
        self.source_path_dir = os.path.dirname(source_path)
        self.source_path_hash = hash_path(source_path)
        self.event_name = event
        self.file_name = os.path.basename(source_path)
        self.dotted_file_ext = os.path.splitext(self.file_name)[1].lower()
        self.file_ext = self.dotted_file_ext.split('.')[1]
        self.file_type = self.get_file_type()
        self.capture_date = get_capture_date(source_path,self.file_type)
        self.store_originals = config['store_originals']
        self.destination_path = self.set_destination_path()
        self.destination_originals_path = ''


        self.filehash = '' # Only populate this one if it's called upon.

    def set_destination_path(self):
        """ set the destination path for the file """

        p = self.configuration['folders']['destination']['base'] + '/' \
            + self.capture_date[0] + '/' \
            + self.capture_date[0] + '-' \
            + self.capture_date[1] + '/' \
            + self.capture_date[0] + '-' \
            + self.capture_date[1] + '-' \
            + self.capture_date[2]

        if self.event_name:
            p = p + '-' + self.event_name

        if self.file_type == 'image':
            p = p + '/PHOTO'
            if self.file_ext.lower() in ('jpg', 'jpeg'):
                if self.store_originals is True:
                    self.destination_originals_path = p + '/ORIGINALS/JPG'
                p = p + '/JPG'
            else:
                if self.store_originals is True:
                    self.destination_originals_path = p + '/ORIGINALS/RAW'
                p = p + '/RAW'
        elif self.file_type == 'video':
            p = p + '/VIDEO'
        elif self.file_type == 'audio':
            p = p + '/AUDIO'
        else:
            log.critical(f'{self.file_type} is not known. You should have never landed here.')

        return p

    def generate_hash(self):
        """ generate the hash and store it to self.filehash """
        return xx_hash(self.source_path_dir)

    def set_hash(self):
        """set the hash for the file """
        self.filehash = self.generate_hash()

    def get_hash(self):
        """ a function to get return the hash """

        if not self.filehash:
            self.set_hash()

        return self.filehash

    def get_file_type(self):
        """ determine if the extension is in the list of file types """
        log.debug(f'get_file_type():')
        for t in self.configuration['file_types']:
            log.debug(f'Checking if file is part of {t}')

            for e in self.configuration['file_types'][t]:
                log.debug(f'Checking if {self.file_ext.lower()} ends with {e}')

                if self.file_ext.lower().endswith(e):
                    log.debug(self.file_ext + ' ends with ' + e)
                    return t
                else:
                    log.debug(self.file_ext + f' does not end with {e}')

def get_capture_date(path, f_type):
    """ get capture date from meta """
    log.debug(f'get_capture_date({path}, {f_type}')

    if f_type == 'image':
        stamp = get_image_date(path)

    elif f_type == 'video':
        try:
            stamp = datetime.strptime(
                    ffmpeg.probe(path)['format']['tags']['creation_time'],
                        '%Y-%m-%dT%H:%M:%S.%f%z')
        except:
            try:
                stamp = datetime.fromtimestamp(os.path.getctime(path))
            except:
                try:
                    stamp = datetime.strptime(
                            str('1900:01:01 00:00:00'), '%Y:%m:%d %H:%M:%S')
                except:
                    log.critical(f'\nCould not get timestamp for {path}.  Giving up.')
                    sys.exit()

    elif f_type == 'audio':
        try:
            stamp = datetime.strptime(ffmpeg.probe(
                path)['format']['tags']['date'], '%Y-%m-%d')
        except KeyError as ke:
            log.warning(f'\nError: {ke} for {path}.  Trying getctime...')
            try:
                stamp = datetime.fromtimestamp(os.path.getctime(path))
            except:
                log.critical(f'\nCould not get timestamp for {path}.  Giving up.')
                sys.exit()
    else:
        try:
            stamp = datetime.fromtimestamp(os.path.getctime(path))
        except:
            log.critical(f'\nCould not get timestamp for {path}.  Giving up.')
            sys.exit()

    year = stamp.strftime("%Y")
    month = stamp.strftime("%m")
    day = stamp.strftime("%d")
    return year, month, day

# def process_file(path_name, f_name, event, c):
#     """ gather information and add to dictionary """
#     log.debug(f'process_file({path_name}, {f_name}, {event}, {c})')
#
#     m = Media(os.path.join(path_name,f_name),event, c)
#     i = m.source_path_hash
#     log.debug(f'Source Path Hash: {i}')
#
#     files[i] = { 'folders': {}, 'date': {} }
#
#     files[i]['folders']['source_path'] = m.source_path_dir
#     files[i]['type'] = m.file_type
#     files[i]['name'] = m.file_name
#     files[i]['extension'] = m.file_ext
#     files[i]['date']['capture_date'] = {}
#     files[i]['date']['capture_date']['y'] = m.capture_date[0]
#     files[i]['date']['capture_date']['m'] = m.capture_date[1]
#     files[i]['date']['capture_date']['d'] = m.capture_date[2]
#     files[i]['folders']['destination'] = m.destination_path
#     files[i]['folders']['destination_original'] = m.destination_originals_path
