# -*- coding: UTF-8 -*-

__revision__ = '$Id$'

# TODO: this library has issues and is not functional

# Copyright © 2009 Piotr Ożarowski
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published byp
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

# You may use and distribute this software under the terms of the
# GNU General Public License, version 2 or later

import logging
import os
from urllib.request import urlcleanup, urlretrieve
from gi.repository import Gtk
from PIL import Image

import gutils
from plugins.extensions import GriffithExtensionBase as Base
from widgets import populate_results_window
from edit import update_image
from gettext import gettext as _
from movie import create_tempfile
import requests

import amazon

log = logging.getLogger('Griffith')


class GriffithExtension(Base):
    name = 'Amazon'
    description = _('Fetch from Amazon')
    author = 'Piotr Ożarowski'
    email = 'piotr@griffith.cc'
    version = 1
    api = 1
    enabled = False

    preferences = {'locale': {'name': _('Select source'),
                              'default': 'US',
                              'type': ('US', 'UK', 'DE', 'CA', 'FR', 'JP')},
                   'accesskey': {'name': _('Access Key ID'),
                                 'hint': _('Get your Access Key ID from ') + 'https://affiliate-program.amazon.com/gp/flex/advertising/api/sign-in.html',
                                 'default': '',
                                 'type': str},
                   'secretkey': {'name': _('Secret Key'),
                                 'hint': _('Get your Secret Key from ') + 'https://affiliate-program.amazon.com/gp/flex/advertising/api/sign-in.html',
                                 'default': '',
                                 'type': str}}
    toolbar_icon = 'ge_amazon.png'

    def toolbar_icon_clicked(self, widget, movie):
        log.info('fetching poster from Amazon...')
        self.movie = movie

        locale = self.get_config_value('locale', 'US').lower()
        accesskey = self.get_config_value('accesskey')
        secretkey = self.get_config_value('secretkey')

        if not accesskey or not secretkey:
            gutils.error(_('Please configure your Amazon Access Key ID and Secret Key correctly in the preferences dialog.'))
            return False

        if movie is None:
            gutils.error(_('You have no movies in your database'), self.widgets['window'])
            return False

        keyword = movie.o_title
        if locale == 'de':
            keyword = movie.title

        try:
            amazon.setLicense(accesskey, secretkey)
            result = amazon.searchByTitle(keyword, type='Large', product_line='DVD', locale=locale)
            if hasattr(result, 'TotalPages'):
                # get next result pages
                pages = int(result.TotalPages)
                page = 2
                while page <= pages and page < 11:
                    tmp = amazon.searchByTitle(keyword, type='Large', product_line='DVD', locale=locale, page=page)
                    result.Item.extend(tmp.Item)
                    page = page + 1
            if not hasattr(result, 'Item') or not len(result.Item):
                # fallback if nothing is found by title
                result = amazon.searchByKeyword(keyword, type='Large', product_line='DVD', locale=locale)
                if hasattr(result, 'TotalPages'):
                    # get next result pages
                    pages = int(result.TotalPages)
                    page = 2
                    while page <= pages and page < 11:
                        tmp = amazon.searchByKeyword(keyword, type='Large', product_line='DVD', locale=locale, page=page)
                        result.Item.extend(tmp.Item)
                        page = page + 1
            self._result = result
            log.info("... %s posters found" % result.TotalResults)
        except Exception:
            log.exception('')
            gutils.warning(_('No posters found for this movie.'))
            return

        if not hasattr(result, 'Item') or not len(result.Item):
            gutils.warning(_('No posters found for this movie.'))
            return

        if len(result.Item) == 1:
            o_title = self.widgets['movie']['o_title'].get_text().decode('utf-8')
            if o_title == result.Item[0].ItemAttributes.Title or keyword == result.Item[0].ItemAttributes.Title:
                self.get_poster(self.app, result.Item[0])
                return

        # populate results window
        items = {}
        for i, item in enumerate(result.Item):
            if hasattr(item, 'LargeImage') and len(item.LargeImage.URL):
                title = item.ItemAttributes.Title
                if hasattr(item.ItemAttributes, 'ProductGroup'):
                    title = title + ' - ' + item.ItemAttributes.ProductGroup
                elif hasattr(item.ItemAttributes, 'Binding'):
                    title = title + ' - ' + item.ItemAttributes.Binding
                if hasattr(item.ItemAttributes, 'ReleaseDate'):
                    title = title + ' - ' + item.ItemAttributes.ReleaseDate[:4]
                elif hasattr(item.ItemAttributes, 'TheatricalReleaseDate'):
                    title = (title + ' - ' +
                             item.ItemAttributes.TheatricalReleaseDate[:4])
                if hasattr(item.ItemAttributes, 'Studio'):
                    title = title + ' - ' + item.ItemAttributes.Studio
                items[i] = title

        populate_results_window(self.app.treemodel_results, items)
        self.widgets['add']['b_get_from_web'].set_sensitive(False) # disable movie plugins (result window is shared)
        self.app._resultswin_process = self.on_result_selected # use this signal (will be reverted when window is closed)
        self.widgets['results']['window'].show()
        self.widgets['results']['window'].set_keep_above(True)

    def on_result_selected(self, key):
        key = int(key)
        if self._result.Item[key].LargeImage.URL:
            poster_file = self.get_poster(self._result.Item[key])
            if poster_file:
                update_image(self.app, self.movie.number, poster_file)
                try:
                    os.remove(poster_file)
                except Exception:
                    log.error('cannot remove %s', poster_file)
        self.widgets['results']['window'].hide()
        self.widgets['add']['b_get_from_web'].set_sensitive(True)

    def get_poster(self, item):
        """Returns file path to the new poster"""

        from movie import Progress, Retriever

        _fd, file_to_copy = create_tempfile()
        file_to_copy += ".jpg"
        canceled = False
        try:
            progress = Progress(
                self.widgets['window'], _("Fetching poster"),
                _("Wait a moment"))
            retriever = Retriever(item.LargeImage.URL, self.widgets['window'],
                                  progress, file_to_copy)
            retriever.start()
            while retriever.is_alive():
                progress.pulse()
                if progress.status:
                    canceled = True
                while Gtk.events_pending():
                    Gtk.main_iteration()
            progress.close()
            urlcleanup()
        except Exception:
            canceled = True
            gutils.warning(_("Sorry. A connection error has occurred."))
            try:
                os.remove(file_to_copy)
            except Exception:
                log.error("no permission for %s" % file_to_copy)

        if not canceled:
            if os.path.isfile(file_to_copy):
                im = None
                try:
                    im = Image.open(file_to_copy)
                except IOError:
                    log.warning("failed to identify %s" % file_to_copy)

                if im and im.size == (1, 1):
                    url = f"http://www.amazon.com/gp/product/images/{item.ASIN}"
                    r = requests.get(url)  # TODO: add headers
                    if r.status_code == 200 and r.content.find('no-img-sm._V47056216_.gif') > 0:
                        log.warning('No image available')
                        gutils.warning(_("Sorry. This movie is listed but has no poster available at Amazon.com."))
                        return False
                    url = gutils.after(url, 'id="imageViewerDiv"><img src="')
                    url = gutils.before(url, '" id="prodImage"')
                    urlretrieve(url, file_to_copy)
                    try:
                        im = Image.open(file_to_copy)
                    except IOError:
                        log.warning("failed to identify %s", file_to_copy)

                if not im:
                    # something wrong with the image, give some feedback to the user
                    log.warning('No image available')
                    gutils.warning(_("Sorry. This movie is listed but has no poster available at Amazon.com."))
                    return False

                if im.mode != 'RGB':  # convert GIFs
                    im = im.convert('RGB')
                    im.save(file_to_copy, 'JPEG')
                # set to None because the file is locked otherwise (os.remove throws an exception)
                im = None

                self.widgets['big_poster'].set_from_file(file_to_copy)

                self.widgets['poster_window'].show()
                self.widgets['poster_window'].move(0, 0)
                if gutils.question(_("Do you want to use this poster instead?"), self.widgets['window']):
                    return file_to_copy
                else:
                    log.info("Reverting to previous poster and deleting new one from disk.")
                    try:
                        os.remove(file_to_copy)
                    except Exception:
                        log.error('cannot remove %s', file_to_copy)

                self.widgets['poster_window'].hide()
            else:
                gutils.warning(_("Sorry. This movie is listed but has no poster available at Amazon.com."))
        else:
            # cleanup temporary files after canceling the download
            if os.path.isfile(file_to_copy):
                try:
                    os.remove(file_to_copy)
                except Exception:
                    log.error('cannot remove %s', file_to_copy)
