# -*- coding: utf-8 -*-
import helper.loghandler

class API():
    def __init__(self, EmbyServer):
        self.EmbyServer = EmbyServer
        self.LOG = helper.loghandler.LOG('EMBY.emby.api.API')
        self.info = "Path,Genres,SortName,Studios,Writer,Taglines,LocalTrailerCount,Video3DFormat,OfficialRating,CumulativeRunTimeTicks,ItemCounts,PremiereDate,ProductionYear,Metascore,AirTime,DateCreated,People,Overview,CommunityRating,StartDate,CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations,Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers,Status,EndDate,MediaSources,VoteCount,RecursiveItemCount,PrimaryImageAspectRatio,DisplayOrder,PresentationUniqueKey,OriginalTitle,AlternateMediaSources,PartCount"
        self.music_info = "Etag,Genres,SortName,Studios,Writer,PremiereDate,ProductionYear,OfficialRating,CumulativeRunTimeTicks,Metascore,CommunityRating,AirTime,DateCreated,MediaStreams,People,ProviderIds,Overview,ItemCounts,PresentationUniqueKey"
        self.browse_info = "Path"

        if self.EmbyServer.Utils.Settings.getDateCreated:
            self.browse_info += ",DateCreated"

        if self.EmbyServer.Utils.Settings.getGenres:
            self.browse_info += ",Genres"

        if self.EmbyServer.Utils.Settings.getStudios:
            self.browse_info += ",Studios"

        if self.EmbyServer.Utils.Settings.getTaglines:
            self.browse_info += ",Taglines"

        if self.EmbyServer.Utils.Settings.getOverview:
            self.browse_info += ",Overview"

        if self.EmbyServer.Utils.Settings.getProductionLocations:
            self.browse_info += ",ProductionLocations"

        if self.EmbyServer.Utils.Settings.getCast:
            self.browse_info += ",People"

    def _http(self, action, url, request):
        request.update({'type': action, 'handler': url})
        return self.EmbyServer.http.request(request, None)

    #Get emby user profile picture.
    def get_user_artwork(self, user_id):
        return "%s/emby/Users/%s/Images/Primary?Format=original" % (self.EmbyServer.Data['auth.server'], user_id)

    def browse_MusicByArtistId(self, Artist_id, Parent_id, Media, Extra):
        params = {
            'ParentId': Parent_id,
            'ArtistIds': Artist_id,
            'IncludeItemTypes': Media,
            'IsMissing': False,
            'Recursive': True,
            'Fields': self.browse_info
        }

        if Extra is not None:
            params.update(Extra)

        return self._http("GET", "Users/%s/Items" % self.EmbyServer.Data['auth.user_id'], {'params': params})

    #Get dynamic listings
    def get_filtered_section(self, data):
        if not 'ViewId' in data:
            data['ViewId'] = None

        if not 'media' in data:
            data['media'] = None

        if not 'limit' in data:
            data['limit'] = None

        if not 'recursive' in data:
            data['recursive'] = True

        params = {
            'ParentId': data['ViewId'],
            'IncludeItemTypes': data['media'],
            'Recursive': data['recursive'],
            'Limit': data['limit'],
            'SortBy': "Random",
            'Fields': self.browse_info
        }

        if 'random' in data:
            if data['random']:
                params['SortBy'] = "Random"

        if 'filters' in data:
            if 'Boxsets' in data['filters']:
                data['filters'].remove('Boxsets')
                params['CollapseBoxSetItems'] = self.EmbyServer.Utils.Settings.groupedSets

            params['Filters'] = ','.join(data['filters'])

        if data['media'] and 'Photo' in data['media']:
            params['Fields'] += ",Width,Height"

        if 'extra' in data:
            if data['extra'] is not None:
                params.update(data['extra'])

        return self._http("GET", "Users/%s/Items" % self.EmbyServer.Data['auth.user_id'], {'params': params})

    def get_recently_added(self, media, parent_id, limit):
        params = {
            'Limit': limit,
            'IncludeItemTypes': media,
            'ParentId': parent_id,
            'Fields': self.browse_info
        }

        if media and 'Photo' in media:
            params['Fields'] += ",Width,Height"

        return self._http("GET", "Users/%s/Items/Latest" % self.EmbyServer.Data['auth.user_id'], {'params': params})

    def get_movies_by_boxset(self, boxset_id):
        for items in self.get_itemsSync(boxset_id, "Movie", False, None):
            yield items

    def get_episode_by_show(self, show_id):
        query = {
            'url': "Shows/%s/Episodes" % show_id,
            'params': {
                'EnableUserData': True,
                'EnableImages': True,
                'UserId': self.EmbyServer.Data['auth.user_id'],
                'Fields': self.info
            }
        }

        for items in self._get_items(query):
            yield items

    def get_episode_by_season(self, show_id, season_id):
        query = {
            'url': "Shows/%s/Episodes" % show_id,
            'params': {
                'SeasonId': season_id,
                'EnableUserData': True,
                'EnableImages': True,
                'UserId': self.EmbyServer.Data['auth.user_id'],
                'Fields': self.info
            }
        }

        for items in self._get_items(query):
            yield items

    def get_itemsSync(self, parent_id, item_type, basic, params):
        query = {
            'url': "Users/%s/Items" % self.EmbyServer.Data['auth.user_id'],
            'params': {
                'ParentId': parent_id,
                'IncludeItemTypes': item_type,
                'Fields': "Etag,PresentationUniqueKey" if basic else self.info,
                'CollapseBoxSetItems': False,
                'IsVirtualUnaired': False,
                'EnableTotalRecordCount': False,
                'LocationTypes': "FileSystem,Remote,Offline",
                'IsMissing': False,
                'Recursive': True
            }
        }

        if params:
            query['params'].update(params)

        for items in self._get_items(query):
            yield items

    def get_artists(self, parent_id, basic, params):
        query = {
            'url': "Artists",
            'params': {
                'UserId': self.EmbyServer.Data['auth.user_id'],
                'ParentId': parent_id,
                'Fields': "Etag,PresentationUniqueKey" if basic else self.music_info,
                'CollapseBoxSetItems': False,
                'IsVirtualUnaired': False,
                'EnableTotalRecordCount': False,
                'LocationTypes': "FileSystem,Remote,Offline",
                'IsMissing': False,
                'Recursive': True
            }
        }

        if params:
            query['params'].update(params)

        for items in self._get_items(query):
            yield items

    def get_albums_by_artist(self, parent_id, artist_id, basic):
        params = {
            'ParentId': parent_id,
            'ArtistIds': artist_id
        }

        for items in self.get_itemsSync(None, "MusicAlbum", basic, params):
            yield items

    def get_songs_by_artist(self, parent_id, artist_id, basic):
        params = {
            'ParentId': parent_id,
            'ArtistIds': artist_id
        }

        for items in self.get_itemsSync(None, "Audio", basic, params):
            yield items

    def get_TotalRecordsRegular(self, parent_id, item_type):
        params = {
            'ParentId': parent_id,
            'IncludeItemTypes': item_type,
            'CollapseBoxSetItems': False,
            'IsVirtualUnaired': False,
            'IsMissing': False,
            'EnableTotalRecordCount': True,
            'LocationTypes': "FileSystem,Remote,Offline",
            'Recursive': True,
            'Limit': 1
        }
        return self._http("GET", "Users/%s/Items" % self.EmbyServer.Data['auth.user_id'], {'params': params})['TotalRecordCount']

    def get_TotalRecordsArtists(self, parent_id):
        params = {
            'UserId': self.EmbyServer.Data['auth.user_id'],
            'ParentId': parent_id,
            'CollapseBoxSetItems': False,
            'IsVirtualUnaired': False,
            'IsMissing': False,
            'EnableTotalRecordCount': True,
            'LocationTypes': "FileSystem,Remote,Offline",
            'Recursive': True,
            'Limit': 1
        }
        return self._http("GET", "Artists", {'params': params})['TotalRecordCount']

    def _get_items(self, query):
        LIMIT = int(self.EmbyServer.Utils.Settings.limitIndex)
        items = {
            'Items': [],
            'RestorePoint': {}
        }
        url = query['url']
        params = query.get('params', {})
        index = params.get('StartIndex', 0)

        while True:
            params['StartIndex'] = index
            params['Limit'] = LIMIT

            try:
                result = self._http("GET", url, {'params': params}) or {'Items': []}
            except Exception as error:
                self.LOG.error("ERROR: %s" % error)
                result = {'Items': []}

            if result['Items'] == []:
                items['TotalRecordCount'] = index
                break

            items['Items'].extend(result['Items'])
            items['RestorePoint'] = query
            yield items
            del items['Items'][:]
            index += LIMIT

    def artwork(self, item_id, art, max_width, ext, index):
        if index is None:
            return "%s/emby/Items/%s/Images/%s?MaxWidth=%s&format=%s" % (self.EmbyServer.Data['auth.server'], item_id, art, max_width, ext)

        return "%s/emby/Items/%s/Images/%s/%s?MaxWidth=%s&format=%s" % (self.EmbyServer.Data['auth.server'], item_id, art, index, max_width, ext)

    def get_users(self, disabled, hidden):
        return self._http("GET", "Users", {'params': {'IsDisabled': disabled, 'IsHidden': hidden}})

    def get_public_users(self):
        return self._http("GET", "Users/Public", {})

    def get_user(self, user_id):
        if user_id is None:
            return self._http("GET", "Users/%s" % self.EmbyServer.Data['auth.user_id'], {})

        return self._http("GET", "Users/%s" % user_id, {})

    def get_views(self):
        return self._http("GET", "Users/%s/Views" % self.EmbyServer.Data['auth.user_id'], {})

    def get_item(self, item_id):
        return self._http("GET", "Users/%s/Items/%s" % (self.EmbyServer.Data['auth.user_id'], item_id), {})

    def get_items(self, item_ids):
        return self._http("GET", "Users/%s/Items" % self.EmbyServer.Data['auth.user_id'], {'params': {'Ids': ','.join(str(x) for x in item_ids), 'Fields': self.info}})

    def get_device(self):
        return self._http("GET", "Sessions", {'params': {'DeviceId': self.EmbyServer.Data['app.device_id']}})

    def get_genres(self, parent_id):
        return self._http("GET", "Genres", {'params': {'ParentId': parent_id, 'UserId': self.EmbyServer.Data['auth.user_id'], 'Fields': self.browse_info}})

    def get_channels(self):
        return self._http("GET", "LiveTv/Channels", {'params': {'UserId': self.EmbyServer.Data['auth.user_id'], 'EnableImages': True, 'EnableUserData': True}})

    def get_intros(self, item_id):
        return self._http("GET", "Users/%s/Items/%s/Intros" % (self.EmbyServer.Data['auth.user_id'], item_id), {})

    def get_additional_parts(self, item_id):
        return self._http("GET", "Videos/%s/AdditionalParts" % item_id, {})

    def get_local_trailers(self, item_id):
        return self._http("GET", "Users/%s/Items/%s/LocalTrailers" % (self.EmbyServer.Data['auth.user_id'], item_id), {})

    def get_ancestors(self, item_id):
        return self._http("GET", "Items/%s/Ancestors" % item_id, {'params': {'UserId': self.EmbyServer.Data['auth.user_id']}})

    def get_themes(self, item_id):
        return self._http("GET", "Items/%s/ThemeMedia" % item_id, {'params': {'UserId': self.EmbyServer.Data['auth.user_id'], 'InheritFromParent': True, 'EnableThemeSongs': True, 'EnableThemeVideos': True}})

    def get_plugins(self):
        return self._http("GET", "Plugins", {})

    def get_seasons(self, show_id):
        return self._http("GET", "Shows/%s/Seasons" % show_id, {'params': {'UserId': self.EmbyServer.Data['auth.user_id'], 'EnableImages': True, 'Fields': self.info}})

    def refresh_item(self, item_id):
        return self._http("POST", "Items/%s/Refresh" % item_id, {'params': {'Recursive': True, 'ImageRefreshMode': "FullRefresh", 'MetadataRefreshMode': "FullRefresh", 'ReplaceAllImages': False, 'ReplaceAllMetadata': True}})

    def favorite(self, item_id, option):
        if option:
            return self._http("POST", "Users/%s/FavoriteItems/%s" % (self.EmbyServer.Data['auth.user_id'], item_id), {})

        return self._http("DELETE", "Users/%s/FavoriteItems/%s" % (self.EmbyServer.Data['auth.user_id'], item_id), {})

    def get_system_info(self):
        return self._http("GET", "System/Configuration", {})

    def post_capabilities(self, data):
        return self._http("POST", "Sessions/Capabilities/Full", {'params': data})

    def session_add_user(self, session_id, user_id, option):
        if option:
            return self._http("POST", "Sessions/%s/Users/%s" % (session_id, user_id), {})

        return self._http("DELETE", "Sessions/%s/Users/%s" % (session_id, user_id), {})

    def session_playing(self, data):
        return self._http("POST", "Sessions/Playing", {'params': data})

    def session_progress(self, data):
        return self._http("POST", "Sessions/Playing/Progress", {'params': data})

    def session_stop(self, data):
        return self._http("POST", "Sessions/Playing/Stopped", {'params': data})

    def item_played(self, item_id, watched):
        if watched:
            return self._http("POST", "Users/%s/PlayedItems/%s" % (self.EmbyServer.Data['auth.user_id'], item_id), {})

        return self._http("DELETE", "Users/%s/PlayedItems/%s" % (self.EmbyServer.Data['auth.user_id'], item_id), {})

    def get_sync_queue(self, date, filters):
        return self._http("GET", "Emby.Kodi.SyncQueue/%s/GetItems" % self.EmbyServer.Data['auth.user_id'], {'params': {'LastUpdateDT': date, 'filter': filters or None}})

    def close_transcode(self):
        return self._http("DELETE", "Videos/ActiveEncodings", {'params': {'DeviceId': self.EmbyServer.Data['app.device_id']}})

    def delete_item(self, item_id):
        return self._http("DELETE", "Items/%s" % item_id, {})
