import os
import sys
import urllib2
import xbmc
import xbmcgui
import xbmcplugin
import socket
import traceback
from quasar.logger import log
from quasar.config import QUASARD_HOST
from quasar.addon import ADDON, ADDON_ID
from quasar.util import notify, getLocalizedString, getLocalizedLabel, system_information

try:
    import simplejson as json
except ImportError:
    import json


HANDLE = int(sys.argv[1])


class closing(object):
    def __init__(self, thing):
        self.thing = thing

    def __enter__(self):
        return self.thing

    def __exit__(self, *exc_info):
        self.thing.close()


class NoRedirectHandler(urllib2.HTTPRedirectHandler):
    def http_error_302(self, req, fp, code, msg, headers):
        import urllib
        infourl = urllib.addinfourl(fp, headers, headers["Location"])
        infourl.status = code
        infourl.code = code
        return infourl
    http_error_300 = http_error_302
    http_error_301 = http_error_302
    http_error_303 = http_error_302
    http_error_307 = http_error_302


def _json(url):
    with closing(urllib2.urlopen(url)) as response:
        if response.code >= 300 and response.code <= 307:
            item = xbmcgui.ListItem(
                path=response.geturl(),
                label=xbmc.getInfoLabel("ListItem.Label"),
                label2=xbmc.getInfoLabel("ListItem.label2"),
                thumbnailImage=xbmc.getInfoLabel("ListItem.Art(thumb)"))
            _infoLabels = {
                "Title": xbmc.getInfoLabel("ListItem.Title"),
                "OriginalTitle": xbmc.getInfoLabel("ListItem.OriginalTitle"),
                "TVShowTitle": xbmc.getInfoLabel("ListItem.TVShowTitle"),
                "Season": xbmc.getInfoLabel("ListItem.Season"),
                "Episode": xbmc.getInfoLabel("ListItem.Episode"),
                "Premiered": xbmc.getInfoLabel("ListItem.Premiered"),
                "Plot": xbmc.getInfoLabel("ListItem.Plot"),
                "PlotOutline": xbmc.getInfoLabel("ListItem.PlotOutline"),
                "Tagline": xbmc.getInfoLabel("ListItem.Tagline"),
                "Year": xbmc.getInfoLabel("ListItem.Year"),
                "Genre": xbmc.getInfoLabel("ListItem.Genre"),
                "Trailer": xbmc.getInfoLabel("ListItem.Trailer"),
                "Studio": xbmc.getInfoLabel("ListItem.Studio"),
                "MPAA": xbmc.getInfoLabel("ListItem.MPAA"),
                "VideoCodec": xbmc.getInfoLabel("ListItem.VideoCodec"),
                "VideoResolution": xbmc.getInfoLabel("ListItem.VideoResolution"),
                "VideoAspect": xbmc.getInfoLabel("ListItem.VideoAspect"),
                "DBID": xbmc.getInfoLabel("ListItem.DBID"),
                "DBTYPE": xbmc.getInfoLabel("ListItem.DBTYPE"),
                "Mediatype": xbmc.getInfoLabel("ListItem.DBTYPE"),
                "Writer": xbmc.getInfoLabel("ListItem.Writer"),
                "Director": xbmc.getInfoLabel("ListItem.Director"),
                "Rating": xbmc.getInfoLabel("ListItem.Rating"),
                "Votes": xbmc.getInfoLabel("ListItem.Votes"),
                "IMDBNumber": xbmc.getInfoLabel("ListItem.IMDBNumber"),
                "Code": xbmc.getInfoLabel("ListItem.IMDBNumber"),
            }
            infoLabels = {}
            for key, value in _infoLabels.iteritems():
                if value:
                    infoLabels[key] = value

            poster = xbmc.getInfoLabel("ListItem.Art(poster)")
            if not poster:
                poster = xbmc.getInfoLabel("ListItem.Art(tvshow.poster)")

            item.setArt({
                "poster": poster,
                "banner": xbmc.getInfoLabel("ListItem.Art(banner)"),
                "fanart": xbmc.getInfoLabel("ListItem.Art(fanart)")
            })

            item.setInfo(type='Video', infoLabels=infoLabels)
            xbmcplugin.setResolvedUrl(HANDLE, True, item)
            return

        payload = response.read()

        try:
            if payload:
                return json.loads(payload)
        except:
            raise Exception(payload)


def run(url_suffix=""):
    if not os.path.exists(os.path.join(xbmc.translatePath(ADDON.getAddonInfo("path")), ".firstrun")):
        notify(getLocalizedString(30101))
        system_information()
        return

    donatePath = os.path.join(xbmc.translatePath(ADDON.getAddonInfo("path")), ".donate")
    if not os.path.exists(donatePath):
        with open(donatePath, "w"):
            os.utime(donatePath, None)
        dialog = xbmcgui.Dialog()
        dialog.ok("Quasar", "Please support Quasar development by visiting https://quasar.surge.sh to donate with Bitcoin, or buying a VPN subscription using the affiliate link at the bottom.")

    socket.setdefaulttimeout(300)
    urllib2.install_opener(urllib2.build_opener(NoRedirectHandler()))

    url = sys.argv[0].replace("plugin://%s" % ADDON_ID, QUASARD_HOST + url_suffix) + sys.argv[2]
    log.debug("Requesting %s from %s" % (url, repr(sys.argv)))

    try:
        data = _json(url)
    except Exception as e:
        map(log.error, traceback.format_exc().split("\n"))
        notify("%s: %s" % (getLocalizedString(30225), repr(e).encode('utf-8')))
        return

    if not data:
        return

    if data["content_type"]:
        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_UNSORTED)
        if data["content_type"] != "tvshows":
            xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE)
        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_DATE)
        xbmcplugin.addSortMethod(HANDLE, xbmcplugin.SORT_METHOD_GENRE)
        xbmcplugin.setContent(HANDLE, data["content_type"])

    listitems = range(len(data["items"]))
    for i, item in enumerate(data["items"]):
        # Translate labels
        if item["label"][0:8] == "LOCALIZE":
            item["label"] = getLocalizedLabel(item["label"])
        if item["label2"][0:8] == "LOCALIZE":
            item["label2"] = getLocalizedLabel(item["label2"])

        listItem = xbmcgui.ListItem(label=item["label"], label2=item["label2"], iconImage=item["icon"], thumbnailImage=item["thumbnail"])
        if item.get("info"):
            listItem.setInfo("video", item["info"])
        if item.get("stream_info"):
            for type_, values in item["stream_info"].items():
                listItem.addStreamInfo(type_, values)
        if item.get("art"):
            listItem.setArt(item["art"])
        if item.get("context_menu"):
            # Translate context menus
            for m, menu in enumerate(item["context_menu"]):
                if menu[0][0:8] == "LOCALIZE":
                    menu[0] = getLocalizedLabel(menu[0])
            listItem.addContextMenuItems(item["context_menu"])
        listItem.setProperty("isPlayable", item["is_playable"] and "true" or "false")
        if item.get("properties"):
            for k, v in item["properties"].items():
                listItem.setProperty(k, v)
        listitems[i] = (item["path"], listItem, not item["is_playable"])

    xbmcplugin.addDirectoryItems(HANDLE, listitems, totalItems=len(listitems))

    # Set ViewMode
    if data["content_type"]:
        viewMode = ADDON.getSetting("viewmode_%s" % data["content_type"])
        try:
            xbmc.executebuiltin('Container.SetViewMode(%s)' % (viewMode))
        except Exception as e:
            log.warning("Unable to SetViewMode(%s): %s" % (viewMode, repr(e)))

    xbmcplugin.endOfDirectory(HANDLE, succeeded=True, updateListing=False, cacheToDisc=True)
