#!/usr/bin/env python
import os.path
import sys
import ffmpeg
import time
from datetime import datetime

class VideoFile:
    def __init__(self,path_file_name,max_width=1024,*args,**kwargs):
        # super(VideoFile, self).__init__(*args, **kwargs)
        self.path_file_name         = path_file_name
        self.max_width              = max_width
        self.out                    = 'thumbnail.jpg'
        self.probe                  = ffmpeg.probe(self.path_file_name)
        self.video_capture_date     = self.get_video_capture_date()
        self.video_stream = None
        self.audio_stream = None

        for i in self.probe['streams']:
            if self.video_stream is None:
                if 'video' == i['codec_type'].lower():
                    self.video_stream       = i
            if self.audio_stream is None:
                if 'audio' == i['codec_type'].lower():
                    self.audio_stream       = i

        self.format_stream          = self.probe['format']
        self.size_width             = self.get_video_width()
        self.size_height            = self.get_video_height()
        self.size                   = self.get_video_size()

        self.stream                 = {}

    @staticmethod
    def convert_from_seconds(seconds):
        return time.strftime("%H:%M:%S", time.gmtime(seconds))

    def gen_video_thumbnail(self):
        """
        Generate a thumbnail from a video
        """
        time_seconds                = self.stream['video']['seconds'] // 5
        v_width                     = int(self.stream['video']['size']['width'])
        width                       = self.set_thumb_width(v_width)

        try:
            (
                ffmpeg.input(
                    self.path_file_name,
                    ss              = time_seconds
                )
                .filter(
                    'scale',
                    width,
                    -1
                )
                .output(
                    self.out,
                    vframes         = 1
                )
                .overwrite_output()
                .run(
                    capture_stdout  = True,
                    capture_stderr  = True
                )
            )
        except ffmpeg.Error as e:
            print(e.stderr.decode(),
                  file              = sys.stderr)

        return self.out

    def set_thumb_width(self, v_width):
        if v_width > self.max_width:
            width                   = self.max_width
        else:
            width                   = v_width

        return width

    def get_video_width(self):
        return self.video_stream['width']

    def get_video_height(self):
        return self.video_stream['height']

    def get_video_size(self):
        if self.size_width is None:
            self.size_width         = self.get_video_width()
        if self.size_height is None:
            self.size_height        = self.get_video_height()
        return f'{self.size_width}x{self.size_height}'

    def get_video_capture_date(self):
        #TODO: refactor this try/except logic.
        try:
            stamp = datetime.strptime(
                self.format_stream['tags']['creation_time'],
                '%Y-%m-%dT%H:%M:%S.%f%z'
            )
        except:
            try:
                stamp               = datetime.fromtimestamp(
                    os.path.getctime(
                        self.path_file_name
                    )
                )
            except:
                stamp               = datetime.strptime(
                    str('1900:01:01 00:00:00'),
                    '%Y:%m:%d %H:%M:%S'
                )
        return stamp

    def video_meta(self):
        self.stream = {
            'video': {
                'bits_per_raw_sample':  self.video_stream['bits_per_raw_sample'],
                'codec_long_name':      self.video_stream['codec_long_name'],
                'duration':             self.convert_from_seconds(float(self.video_stream['duration'])),
                'encoding_brand':       self.format_stream['tags']['major_brand'],
                'pix_fmt':              self.video_stream['pix_fmt'],
                'profile':              self.video_stream['profile'],
                'r_frame_rate':         self.video_stream['r_frame_rate'],
                'size': {
                    'width_height':         self.size,
                    'height':               self.video_stream['height'],
                    'width':                self.video_stream['width']
                }
            },
            'audio': {},
            'format': {}
        }

        return self.stream