# -*- coding: utf-8 -*-

#################################################################################################

import logging
import sqlite3
from contextlib import closing
import sys
import traceback

import xbmc
import xbmcaddon
import xbmcgui
import xbmcplugin
import xbmcvfs

from views import Playlist, VideoNodes
from utils import window, should_stop, settings, language

#################################################################################################

log = logging.getLogger("EMBY."+__name__)
KODI = xbmc.getInfoLabel('System.BuildVersion')[:2]

#################################################################################################

def video_database():
        
    db_version = {

        '13': 78, # Gotham
        '14': 90, # Helix
        '15': 93, # Isengard
        '16': 99, # Jarvis
        '17': 107 # Krypton
    }

    path = xbmc.translatePath("special://database/MyVideos%s.db"
        % db_version.get(KODI, "")).decode('utf-8')

    return path

def music_database():
    
    db_version = {

        '13': 46, # Gotham
        '14': 48, # Helix
        '15': 52, # Isengard
        '16': 56, # Jarvis
        '17': 60  # Krypton
    }

    path = xbmc.translatePath("special://database/MyMusic%s.db"
        % db_version.get(KODI, "")).decode('utf-8')

    return path

def texture_database():
    return xbmc.translatePath("special://database/Textures13.db").decode('utf-8')

def emby_database():
    return xbmc.translatePath("special://database/emby.db").decode('utf-8')

def kodi_commit():
    # verification for the Kodi video scan
    kodi_scan = window('emby_kodiScan') == "true"
    count = 0

    while kodi_scan:
        log.info("kodi scan is running, waiting...")

        if count == 10:
            log.info("flag still active, but will try to commit")
            window('emby_kodiScan', clear=True)

        elif should_stop() or xbmc.Monitor().waitForAbort(1):
            log.info("commit unsuccessful. sync terminating")
            return False

        kodi_scan = window('emby_kodiScan') == "true"
        count += 1

    return True


class DatabaseConn(object):
    # To be called as context manager - i.e. with DatabaseConn() as conn: #dostuff

    def __init__(self, database_file="video", commit_on_close=True, timeout=120):
        """
        database_file can be custom: emby, texture, music, video, :memory: or path to the file
        commit_mode set to None to autocommit (isolation_level). See python documentation.
        """
        self.db_file = database_file
        self.commit_on_close = commit_on_close
        self.timeout = timeout

    def __enter__(self):
        # Open the connection
        self.path = self._SQL(self.db_file)
        log.info("opening: %s", self.path)
        #traceback.print_stack()
        
        if settings('dblock') == "true":
            self.conn = sqlite3.connect(self.path, isolation_level=None, timeout=self.timeout)
        else:
            self.conn = sqlite3.connect(self.path, timeout=self.timeout)
            
        return self.conn

    def _SQL(self, media_type):

        databases = {
            'emby': emby_database,
            'texture': texture_database,
            'music': music_database,
            'video': video_database
        }
        return databases[media_type]() if media_type in databases else self.db_file

    def __exit__(self, exc_type, exc_val, exc_tb):
        # Close the connection
        changes = self.conn.total_changes

        if exc_type is not None:
            # Errors were raised in the with statement
            log.error("Type: %s Value: %s", exc_type, exc_val)

        if self.commit_on_close == True and changes:
            log.info("number of rows updated: %s", changes)
            if self.db_file == "video":
                kodi_commit()
            self.conn.commit()
            log.info("commit: %s", self.path)

        log.info("closing: %s", self.path)
        self.conn.close()

        
def db_reset():

    dialog = xbmcgui.Dialog()

    if not dialog.yesno(language(29999), language(33074)):
        return

    # first stop any db sync
    window('emby_online', value="reset")
    window('emby_shouldStop', value="true")
    count = 10
    while window('emby_dbScan') == "true":
        log.info("Sync is running, will retry: %s..." % count)
        count -= 1
        if count == 0:
            dialog.ok(language(29999), language(33085))
            return
        xbmc.sleep(1000)

    # Clean up the playlists
    Playlist().delete_playlists()

    # Clean up the video nodes
    VideoNodes().deleteNodes()

    # Wipe the kodi databases
    log.warn("Resetting the Kodi video database.")
    with DatabaseConn('video') as conn:
        with closing(conn.cursor()) as cursor:
            cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
            rows = cursor.fetchall()
            for row in rows:
                tablename = row[0]
                if tablename != "version":
                    cursor.execute("DELETE FROM " + tablename)

    if settings('enableMusic') == "true":
        log.warn("Resetting the Kodi music database.")
        with DatabaseConn('music') as conn:
            with closing(conn.cursor()) as cursor:           
                cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
                rows = cursor.fetchall()
                for row in rows:
                    tablename = row[0]
                    if tablename != "version":
                        cursor.execute("DELETE FROM " + tablename)

    # Wipe the emby database
    log.warn("Resetting the Emby database.")
    with DatabaseConn('emby') as conn:
        with closing(conn.cursor()) as cursor:    
            cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
            rows = cursor.fetchall()
            for row in rows:
                tablename = row[0]
                if tablename != "version":
                    cursor.execute("DELETE FROM " + tablename)
            cursor.execute('DROP table IF EXISTS emby')
            cursor.execute('DROP table IF EXISTS view')
            cursor.execute("DROP table IF EXISTS version")

    # Offer to wipe cached thumbnails
    if dialog.yesno(language(29999), language(33086)):
        log.warn("Resetting all cached artwork")
        # Remove all existing textures first
        import artwork
        artwork.Artwork().delete_cache()

    # reset the install run flag
    settings('SyncInstallRunDone', value="false")

    # Remove emby info
    resp = dialog.yesno(language(29999), language(33087))
    if resp:
        import connectmanager
        # Delete the settings
        addon = xbmcaddon.Addon()
        addondir = xbmc.translatePath(
                   "special://profile/addon_data/plugin.video.emby/").decode('utf-8')
        dataPath = "%ssettings.xml" % addondir
        xbmcvfs.delete(dataPath)
        connectmanager.ConnectManager().clear_data()

    dialog.ok(heading=language(29999), line1=language(33088))
    xbmc.executebuiltin('RestartApp')
    return xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xbmcgui.ListItem())