#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals
from logging import getLogger

from .. import plex_functions as PF, utils, timing, variables as v, app

LOG = getLogger('PLEX.sync.time')


def sync_pms_time():
    """
    PMS does not provide a means to get a server timestamp. This is a work-
    around - because the PMS might be in another time zone

    In general, everything saved to Kodi shall be in Kodi time.

    Any info with a PMS timestamp is in Plex time, naturally
    """
    LOG.info('Synching time with PMS server')
    # Find a PMS item where we can toggle the view state to enforce a
    # change in lastViewedAt

    # Get all Plex libraries
    sections = PF.get_plex_sections()
    try:
        sections.attrib
    except AttributeError:
        LOG.error("Error download PMS views, abort sync_pms_time")
        return False

    plex_id = None
    typus = (
        (v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_MOVIE,),
        (v.PLEX_TYPE_SHOW, v.PLEX_TYPE_EPISODE),
        (v.PLEX_TYPE_ARTIST, v.PLEX_TYPE_SONG)
    )
    for section_type, plex_type in typus:
        if plex_id:
            break
        for section in sections:
            if plex_id:
                break
            if not section.attrib['type'] == section_type:
                continue
            library_id = section.attrib['key']
            try:
                iterator = PF.SectionItems(library_id, plex_type=plex_type)
                for item in iterator:
                    if item.get('viewCount'):
                        # Don't want to mess with items that have playcount>0
                        continue
                    if item.get('viewOffset'):
                        # Don't mess with items with a resume point
                        continue
                    plex_id = utils.cast(int, item.get('ratingKey'))
                    LOG.info('Found a %s item to sync with: %s',
                             plex_type, plex_id)
                    break
            except RuntimeError:
                pass
    if plex_id is None:
        LOG.error("Could not find an item to sync time with")
        LOG.error("Aborting PMS-Kodi time sync")
        return False

    # Get the Plex item's metadata
    xml = PF.GetPlexMetadata(plex_id)
    if xml in (None, 401):
        LOG.error("Could not download metadata, aborting time sync")
        return False

    timestamp = xml[0].get('lastViewedAt')
    if timestamp is None:
        timestamp = xml[0].get('updatedAt')
        LOG.debug('Using items updatedAt=%s', timestamp)
        if timestamp is None:
            timestamp = xml[0].get('addedAt')
            LOG.debug('Using items addedAt=%s', timestamp)
            if timestamp is None:
                timestamp = 0
                LOG.debug('No timestamp; using 0')
    timestamp = utils.cast(int, timestamp)
    # Set the timer
    koditime = timing.unix_timestamp()
    # Toggle watched state
    PF.scrobble(plex_id, 'watched')
    # Let the PMS process this first!
    app.APP.monitor.waitForAbort(1)
    # Get updated metadata
    xml = PF.GetPlexMetadata(plex_id)
    # Toggle watched state back
    PF.scrobble(plex_id, 'unwatched')
    try:
        plextime = xml[0].get('lastViewedAt')
    except (IndexError, TypeError, AttributeError):
        LOG.error('Could not get lastViewedAt - aborting')
        return False

    # Calculate time offset Kodi-PMS
    timing.KODI_PLEX_TIME_OFFSET = float(koditime) - float(plextime)
    utils.settings('kodiplextimeoffset',
                   value=str(timing.KODI_PLEX_TIME_OFFSET))
    LOG.info("Time offset Koditime - Plextime in seconds: %s",
             timing.KODI_PLEX_TIME_OFFSET)
    return True