import json
import logging

from lxml import etree
from pkg_resources import resource_string, resource_listdir

from django.http import Http404

from xmodule.x_module import XModule
from xmodule.raw_module import RawDescriptor
from xmodule.modulestore.mongo import MongoModuleStore
from xmodule.modulestore.django import modulestore
from xmodule.contentstore.content import StaticContent

import datetime
import time

log = logging.getLogger(__name__)


class VideoAlphaModule(XModule):
    video_time = 0
    icon_class = 'video'

    js = {
        'js': [resource_string(__name__, 'js/src/videoalpha/display/html5_video.js')],
        'coffee':
        [resource_string(__name__, 'js/src/time.coffee'),
         resource_string(__name__, 'js/src/videoalpha/display.coffee')] +
        [resource_string(__name__, 'js/src/videoalpha/display/' + filename)
         for filename
         in sorted(resource_listdir(__name__, 'js/src/videoalpha/display'))
         if filename.endswith('.coffee')]}
    css = {'scss': [resource_string(__name__, 'css/videoalpha/display.scss')]}
    js_module_name = "VideoAlpha"

    def __init__(self, system, location, definition, descriptor,
                 instance_state=None, shared_state=None, **kwargs):
        XModule.__init__(self, system, location, definition, descriptor,
                         instance_state, shared_state, **kwargs)
        xmltree = etree.fromstring(self.definition['data'])
        self.youtube = xmltree.get('youtube')
        self.sub = xmltree.get('sub')
        self.position = 0
        self.show_captions = xmltree.get('show_captions', 'true')
        self.sources = {
            'main': self._get_source(xmltree),
            'mp4': self._get_source(xmltree, ['mp4']),
            'webm': self._get_source(xmltree, ['webm']),
            'ogv': self._get_source(xmltree, ['ogv']),
        }
        self.track = self._get_track(xmltree)
        self.start_time, self.end_time = self._get_timeframe(xmltree)

        if instance_state is not None:
            state = json.loads(instance_state)
            if 'position' in state:
                self.position = int(float(state['position']))

    def _get_source(self, xmltree, extensions=['mp4', 'ogv', 'avi', 'webm']):
        """Find the first valid source, which ends with one of
        `extensions`."""
        condition = lambda src: any([src.endswith(ext) for ext in extensions])
        return self._get_first_external(xmltree, 'source', condition)

    def _get_track(self, xmltree):
        # find the first valid track
        return self._get_first_external(xmltree, 'track')

    def _get_first_external(self, xmltree, tag, condition=bool):
        """Will return the first 'valid' element of the given tag.
        'valid' means that `condition('src' attribute) == True`
        """
        result = None

        for element in xmltree.findall(tag):
            src = element.get('src')
            if condition(src):
                result = src
                break
        return result

    def _get_timeframe(self, xmltree):
        """ Converts 'from' and 'to' parameters in video tag to seconds.
        If there are no parameters, returns empty string. """

        def parse_time(s):
            """Converts s in '12:34:45' format to seconds. If s is
            None, returns empty string"""
            if s is None:
                return ''
            else:
                x = time.strptime(s, '%H:%M:%S')
                return datetime.timedelta(hours=x.tm_hour,
                                      minutes=x.tm_min,
                                      seconds=x.tm_sec).total_seconds()

        return parse_time(xmltree.get('from')), parse_time(xmltree.get('to'))

    def handle_ajax(self, dispatch, get):
        '''
        Handle ajax calls to this video.
        TODO (vshnayder): This is not being called right now, so the position
        is not being saved.
        '''
        log.debug(u"GET {0}".format(get))
        log.debug(u"DISPATCH {0}".format(dispatch))
        if dispatch == 'goto_position':
            self.position = int(float(get['position']))
            log.info(u"NEW POSITION {0}".format(self.position))
            return json.dumps({'success': True})
        raise Http404()

    def get_progress(self):
        ''' TODO (vshnayder): Get and save duration of youtube video, then return
        fraction watched.
        (Be careful to notice when video link changes and update)

        For now, we have no way of knowing if the video has even been watched, so
        just return None.
        '''
        return None

    def get_instance_state(self):
        #log.debug(u"STATE POSITION {0}".format(self.position))
        return json.dumps({'position': self.position})

    def videoalpha_list(self):
        return self.youtube

    def get_html(self):
        if isinstance(modulestore(), MongoModuleStore):
            caption_asset_path = StaticContent.get_base_url_path_for_course_assets(self.location) + '/subs_'
        else:
            # VS[compat]
            # cdodge: filesystem static content support.
            caption_asset_path = "/static/{0}/subs/".format(self.metadata['data_dir'])

        return self.system.render_template('videoalpha.html', {
            'streams': self.videoalpha_list(),
            'id': self.location.html_id(),
            'position': self.position,
            'sub': self.sub,
            'sources': self.sources,
            'track': self.track,
            'display_name': self.display_name,
            # TODO (cpennington): This won't work when we move to data that isn't on the filesystem
            'data_dir': self.metadata['data_dir'],
            'caption_asset_path': caption_asset_path,
            'show_captions': self.show_captions,
            'start': self.start_time,
            'end': self.end_time
        })


class VideoAlphaDescriptor(RawDescriptor):
    module_class = VideoAlphaModule
    stores_state = True
    template_dir_name = "videoalpha"

@@ -4269,352 +4269,8 @@
 ()%0A%0A
-    def get_progress(self):%0A        ''' TODO (vshnayder): Get and save duration of youtube video, then return%0A        fraction watched.%0A        (Be careful to notice when video link changes and update)%0A%0A        For now, we have no way of knowing if the video has even been watched, so%0A        just return None.%0A        '''%0A        return None%0A%0A
     
@@ -5010,47 +5010,8 @@
 (),%0A
-            'position': self.position,%0A
     

remove unnecessary code