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

__revision__ = '$Id'

# Written by Wolfgang Friebel <wp.friebel@gmail.com>
# Copyright (©) 2025 Wolfgang Friebel
# based on latest version of PluginMovieIMDB.py, V. Nunes, P. 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 by
# 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 gutils
import movie
import re
import logging
from bs4 import BeautifulSoup
import requests
from dataclasses import dataclass

log = logging.getLogger('Griffith')

plugin_name = 'OFDb'
plugin_description = 'Online-Filmdatenbank'
plugin_url = 'www.ofdb.de'
plugin_language = _('Deutsch')
plugin_author = 'W.Friebel'
plugin_author_email = 'wp.friebel@gmail.com'
plugin_version = '0.90'

@dataclass
class MovieInfo:
    title: str
    movie_id: str
    extra_info: str


class Plugin(movie.Movie):
    def __init__(self, movie_id):
        self.page_main = None
        self.page_cast = None
        self.page_plot = None
        self.encode = 'utf-8'
        self.movie_id = movie_id
        self.url = f"https://www.ofdb.de/film/{self.movie_id}/"
        self.soup = None
        self.soup_cast = None
        self.soup_plot = None
        self.fassung = {}

    def initialize(self):
        self.page_main = self.open_page(url=self.url)
        self.soup = BeautifulSoup(self.page_main, 'html.parser')
        self.page_cast = self.open_page(url=self.url + 'details')
        self.soup_cast = BeautifulSoup(self.page_cast, 'html.parser')
        ploturl = self.soup.find('span', {'itemprop': 'description'})
        if (ploturl):
            ploturl = ploturl.parent.a['href']
            plotpage = requests.get(ploturl, headers=self.config.http_header)
            self.soup_plot = BeautifulSoup(plotpage.content, 'html.parser')

    def get_details(self, item):
        if (not self.fassung):
            fassungurl = self.soup.find(href=re.compile(f"www.ofdb.de/fassung/{self.movie_id},"))
            if (not fassungurl):
                fassungurl = self.soup.find(href=re.compile("www.ofdb.de/fassung/"))
            fassungurl = fassungurl['href']
            fassungpage = requests.get(fassungurl, headers=self.config.http_header)
            self.soup_fassung = BeautifulSoup(fassungpage.content, 'html.parser')
            fassung = self.soup_fassung.find('div', {'class': 'bodytext-fassung'})
            fassung = (fassung.text.replace('\n\n', '\n'))
            key = ''
            for l in fassung.split('\n'):
                lstrip = l.strip()
                if (':' in lstrip and lstrip[-1] == ':'):
                    key = lstrip
                else:
                    if(lstrip and key):
                        self.fassung[key] = lstrip + '\n'
        if (item in self.fassung):
            return self.fassung[item]
        else:
            return ''
    def get_image(self):
        image = self.soup.find('meta', {'property': 'og:image'})
        self.image_url = image['content']

    def get_o_title(self):
        if (self.soup_plot):
            for li in self.soup_plot.find('ul',{'class': 'link_list-moviedetails'}).find_all('li'):
                if (li.text == 'Originaltitel:'):
                    self.o_title = li.next_sibling.next_sibling.text.strip()

    def get_title(self):
        title = self.soup.find('meta', {'property': 'og:title'})
        self.title = title['content'].strip()

    def get_director(self):
        director = self.soup.find('span', {'itemprop': 'director'}).text.strip()
        self.director = director

    def get_plot(self):
        if (self.soup_plot):
            detail = self.soup_plot.find('div', {'class': 'bodytext'}).find('h4')
            detail2 = detail.next_element.next_element.next_element
            self.plot = detail.text.replace(' ...', '') + detail2.text.replace('... ', '')
        else:
            #self.plot = 'Zu diesem Film gibt es noch keine Inhaltsangabe'
            self.plot = ''

    def get_year(self):
        self.year = self.soup.find(href=re.compile("erscheinungsjahr")).text

    def get_runtime(self):
        time = self.get_details('Laufzeit:')
        hms = re.findall(r'\b\d+:\d+:\d+\b', time)
        ms = re.findall(r'\b\d+:\d+\b', time)
        m = re.findall(r'\b\d+\b', time)
        if (hms):
            hms = re.findall(r'\b\d+\b', time)
            self.runtime = 60*hms[0] + hms[1]
        else:
            if (ms):
                ms = re.findall(r'\b\d+\b', time)
                self.runtime = ms[0]
            else:
                if (m):
                    self.runtime = m[0]


    def get_genre(self):
        genres = self.soup.find_all('span', {'itemprop': 'genre'})
        genre = []
        for g in genres:
            genre.append(g.text.strip())
        self.genre = ', '.join(genre)

    def get_cast(self):
        self.cast = ''
        actors = self.soup.find_all('li', {'itemprop': 'actor'})
        actor_url = []
        cast = []
        for actor in actors:
            actor_url.append(actor.a['href'])
        for url in actor_url:
            roles = self.soup_cast.find_all('a', {'href': url})
            for role in roles:
                if (role.text):
                    role = role.parent.text.strip()
                    role = role.replace("\n", '')
                    if ('Rollenname' in role):
                        cast.append(role.replace("Rollenname:", ' als'))

        self.cast = "\n".join(cast)

    def get_classification(self):
        """
        The url provides the classification in one or more countries. It would
        be a lot more effort to parse this page since the country to be used
        must be defined and a fallback if no country is defined or the country
        which is defined is not in the list of classifications.
        """
        self.classification = self.get_details('Freigabe:')

    def get_studio(self):
        self.studio = ''

    def get_o_site(self):
        self.o_site = ''

    def get_site(self):
        self.site = f"https://www.ofdb.de/title/tt{self.movie_id}/"

    def get_trailer(self):
        """
        Sets the trailer URL but does not check if actually trailers exist.
        """
        self.trailer = f"https://www.ofdb.de/title/tt{self.movie_id}/trailers"

    def get_country(self):
        country = self.soup.find('span', {'itemprop': 'countryOfOrigin'}).text
        self.country = country

    def get_rating(self):
        rating = self.soup.find('div', {'class':'progress-bar'}).text.strip()
        self.rating = rating

    def get_notes(self):
        self.notes = ''
        notes = ['Bildformat:' + self.get_details('Bildformat:'),
                 'Tonformat:' + self.get_details('Tonformat:'),
                 'Untertitel:' + self.get_details('Untertitel:')]
        self.notes = '\n'.join(notes)
        color_value = ''
        sound_value = []
        language_value = ''

    def get_screenplay(self):
        self.screenplay = ''

    def get_cameraman(self):
        self.cameraman = ''

class SearchPlugin(movie.SearchMovie):

    def __init__(self):
        """
        https://www.ofdb.de/find?s=tt;q=
        Seems to give the best results. 25 results for "Damages", popular titles
        first.
        """
        super().__init__()
        self.original_url_search = "https://www.ofdb.de/suchergebnis/?"
        self.translated_url_search = "https://www.ofdb.de/suchergebnis/?"
        self.encode = 'utf8'
        self.page = None

    def search(self, parent_window):
        if not self.open_search(parent_window):
            return None
        return self.page

    def get_searches(self):
        movie_id = ''
        soup = BeautifulSoup(self.page, 'html.parser')
        movie_tr_items = soup.find('tbody').find_all( 'tr')
        for movie_item in movie_tr_items:
            movie_url = movie_item.a['href']
            if ('/www.ofdb.de/film/' in movie_url):
                tds = movie_item.find_all('td')
                numbers = re.findall(r'\d+', str(tds[2]))
                year = ''
                if (numbers[0]):
                    year = "(" + numbers[0] + ")"
                for movie_entry in movie_item.find('span', {'class': 'tooltipster'}):
                    movie_title = movie_entry.text.strip()
                    numbers = re.findall(r'\d+', movie_url)
                    movie_id = numbers[0]
                movie_additional_infos = movie_item.find_all(
                    'span', {'class': 'smalltext'})
                infos = [year]
                for info in movie_additional_infos:
                    # <span class="smalltext">
                    text = info.text.strip()
                    if (text):
                        infos.append(text)
                movie_info = MovieInfo(movie_title, movie_id, '|'.join(infos))
                self.ids.append(movie_info.movie_id)
                title_info = movie_info.title
                if (movie_info.extra_info):
                    title_info = ' - '.join((movie_info.title,
                                             movie_info.extra_info))
                self.titles.append(title_info)
            else:
                movie_id = ''
            # log.debug(f"movie={movie}\n____")


class SearchPluginTest(SearchPlugin):
    """
    Plugin test for the search plugin
    Configuration for automated tests:
    dict { movie_id -> [ expected result count for original url,
                         expected result count for translated url ] }
    """
    test_configuration = {
        'Damages': [25, 25],
        'Ein glückliches Jahr': [17, 17],
        'Shakespeare in Love': [25, 25],
        }


class PluginTest:
    """
    Plugin test for the extraction of content for a film
    Configuration for automated tests:
    dict { movie_id -> dict { arribute -> value } }

    value: * True/False if attribute only should be tested for any value
           * or the expected value
    """
    test_configuration = {
        '0138097': {
            'title': 'Shakespeare in Love',
            'o_title': 'Shakespeare in Love',
            'director': 'John Madden',
            'plot': True,
            'cast': """Geoffrey Rush as Philip Henslowe
Tom Wilkinson as Hugh Fennyman
Steven O'Donnell as Lambert
Tim McMullan as Frees (as Tim McMullen)
Joseph Fiennes as Will Shakespeare
Steven Beard as Makepeace, the Preacher
Antony Sher as Dr Moth
Patrick Barlow as Will Kempe
Martin Clunes as Richard Burbage
Sandra Reinton as Rosaline
Simon Callow as Tilney, Master of the Revels
Judi Dench as Queen Elizabeth
Bridget McConnell as Lady in Waiting (as Bridget McConnel)
Georgie Glen as Lady in Waiting
Nicholas Boulton as Henry Condell
Gwyneth Paltrow as Viola De Lesseps
Imelda Staunton as Nurse
Colin Firth as Lord Wessex
Desmond McNamara as Crier
Barnaby Kay as Nol
Jim Carter as Ralph Bashford
Paul Bigley as Peter, the Stage Manager
Jason Round as Actor in Tavern
Rupert Farley as Barman
Adam Barker as First Auditionee
Joe Roberts as John Webster
Harry Gostelow as Second Auditionee
Alan Cody as Third Auditionee
Mark Williams as Wabash
David Curtiz as John Hemmings
Gregor Truter as James Hemmings
Simon Day as First Boatman
Jill Baker as Lady De Lesseps
Amber Glossop as Scullery Maid
Robin Davies as Master Plum
Hywel Simons as Servant
Nicholas Le Prevost as Sir Robert De Lesseps
Ben Affleck as Ned Alleyn
Timothy Kightley as Edward Pope
Mark Saban as Augustine Philips
Bob Barrett as George Bryan
Roger Morlidge as James Armitage
Daniel Brocklebank as Sam Gosse
Roger Frost as Second Boatman
Rebecca Charles as Chambermaid
Richard Gold as Lord in Waiting
Rachel Clarke as First Whore
Lucy Speed as Second Whore
Patricia Potter as Third Whore
John Ramm as Makepeace's Neighbour
Martin Neely as Paris / Lady Montague (as Martin Neeley)
The Choir of St. George's School in Windsor as (as The Choir of St George's School Windsor)
Rest of cast listed alphabetically:
Jason Anthony as Nobleman (uncredited)
Steve Apelt as Theatregoer (uncredited)
Paul Bannon as Theatre Attendee (uncredited)
Matthew Christian as Queen Elizabeth I Party Guest (uncredited)
Kelley Costigan as Theatregoer (uncredited)
Matthew Crosby as Theatregoer (uncredited)
Rupert Everett as Christopher Marlowe (uncredited)
Russell Greening as Thomas Crown (uncredited)
John Inman as Lady Capulet in Play (uncredited)
Carlisle Redthunder as Indian (uncredited)""",
            'country': 'United States',
            'genre': 'Comedy, Drama, History',
            'classification': False,
            'studio': 'Universal Pictures, Miramax, The Bedford Falls Company',
            'o_site': False,
            'site': 'https://www.ofdb.de/title/tt0138097/',
            'trailer': 'https://www.ofdb.de/title/tt0138097/trailers',
            'year': 1998,
            'notes': _('Language') + ': English\n'
                     + _('Audio') + ': Dolby Digital, DTS, SDDS\n'
                     + _('Color') + ': Color',
#             'notes': _('Language') + ': English\n'
#                      + _('Audio') + ': Dolby Digital, DTS, SDDS\n'
#                      + _('Color') + ': Color\n\
# Tagline: ...A Comedy About the Greatest Love Story Almost Never Told...\n\
# Love is the only inspiration',
            'runtime': 123,
            'image': True,
            'rating': 7.0,
            # 'screenplay': 'Marc Norman, Tom Stoppard',
            'screenplay': '',
            # 'cameraman': 'Richard Greatrex',
            'cameraman': '',
            'barcode': False
            },
        }
