#!/usr/bin/env python
# -*- coding: utf-8 -*-
# GPL. (C) 2025 Paolo Patruno.
# 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 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 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
# 
from autoradio import daemon
from autoradio.mpris2.mediaplayer2 import MediaPlayer2
from autoradio.mpris2.player import Player
from autoradio.mpris2.tracklist import TrackList
from autoradio.mpris2.interfaces import Interfaces
from autoradio.mpris2.some_players import Some_Players
from autoradio.mpris2.utils import get_players_uri
from autoradio.mpris2.utils import get_session
import dbus

from datetime import date,datetime,timedelta
import time
import requests
import urllib.parse

import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'autoradio.settings'
from django.conf import settings
import django

import autoradio.settings
import autoradio.autoradio_config
from autoradio import _version_
import logging,errno,signal,logging.handlers

# check schedule every timedelta
timestep=timedelta(seconds=15)

nexttimeadvice=timedelta(seconds=300)

metatraced = daemon.Daemon(
        stdin="/dev/null",
        stdout=autoradio.settings.logfileautoradiometatrace,
        stderr=autoradio.settings.errfileautoradiometatrace,
        pidfile=autoradio.settings.lockfileautoradiometatrace,
        user=autoradio.settings.userautoradiometatrace,
        group=autoradio.settings.groupautoradiometatrace
)

def main():

    current_title=None
    current_title_log=None
    next_title=None
    next_artist=None
    spare=False
    title=None
    
    django.setup()
    import autoradio.autoradio_core

    formatter=logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s",datefmt="%Y-%m-%d %H:%M:%S")
    handler = logging.handlers.RotatingFileHandler(autoradio.settings.logfileautoradiometatrace, maxBytes=5000000, backupCount=10)
    handler.setFormatter(formatter)
    # Add the log message handler to the root logger
    logging.getLogger().addHandler(handler)
    logging.getLogger().setLevel(logging.INFO)

    metatraceformatter=logging.Formatter("%(asctime)s;%(message)s;",datefmt="%Y-%m-%d %H:%M:%S")
    metatracehandler = logging.handlers.RotatingFileHandler(autoradio.settings.fileautoradiometatrace, maxBytes=5000000, backupCount=10)
    metatracehandler.setFormatter(metatraceformatter)
    metatracelogger=logging.getLogger("metatracelogger")
    # Add the log message handler to the metatrace logger
    metatracelogger.addHandler(metatracehandler)
    metatracelogger.setLevel(logging.INFO)
    
    logging.info('Starting up autometatraced version '+_version_)
    
    uris = list(get_players_uri(pattern=".",busaddress=autoradio.settings.busaddressplayer))

    if len(uris) >0 :
        uri=uris[0]

        if autoradio.settings.busaddressplayer is None:
            bus = dbus.SessionBus()
        else:
            bus =dbus.bus.BusConnection(autoradio.settings.busaddressplayer)
            mp2 = MediaPlayer2(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus})
            play = Player(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus})
    else:
        logging.error("No players availables")
        return

            
    while (True):
        pali=autoradio.autoradio_core.palimpsests([])

        now=datetime.now()
        logging.info(f"datetime {now}")
        update=False
        onair=None
        artist=None
        start=None
        end=None
        length=None
        last_message_is_next=False
            
        for program_title,pdatetime_start,pdatetime_end,code,type,subtype,production,note in pali.get_palimpsest(now-timedelta(minutes=600),now+timedelta(minutes=600)):

            if (pdatetime_start <= now and pdatetime_end >now):

                # current program found
                logging.info(f"------> {note} : {program_title} : {type} : {subtype}")
                # check for spot
                if (code == "5"):
                    logging.info(f"--> skip spot")

                # check playlist
                elif (code == "13f"):
                    logging.info(f"--> playlist")
                    try:
                        # get metadataa from player playlist
                        if mp2.HasTrackList:
                            tl = TrackList(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus})
                            id = play.Metadata.get(u'mpris:trackid',None)
                            for track in  tl.GetTracksMetadata( tl.Tracks):
                                if (track.get(u'mpris:trackid',None) == id):
                                    logging.info("--> {} {} {} {} {}".format(track.get(u'mpris:trackid',None),
                                                                      track.get(u'mpris:length',None),
                                                                      track.get(u'xesam:artist',None),
                                                                      track.get(u'xesam:title',None),
                                                                      track.get(u'xesam:url',None)))
                                    file=track.get(u'xesam:url',None)
                                    filepath=os.path.dirname(file)
                                    autopath=settings.MEDIA_ROOT
                                    programpath=settings.MEDIA_ROOT+"podcasts"
                                    position=int(play.Position)
                                    update=True

                                    if ( os.path.commonprefix ((filepath,"file://"+autopath)) == "file://"+autopath):
                                        logging.info("--> skip autoradio file: {}".format(file))
                                        onair="program not in palimpsest"
                                        if ( os.path.commonprefix ((filepath,"file://"+programpath)) == "file://"+programpath):
                                            logging.warning("--> program not in palimpsest file: {}".format(file))
                                            artist="sconosciuto"
                                            title=os.path.splitext(os.path.split(filepath)[1])[0]
                                    else:
                                        onair="playlist"
                                        artist=track.get(u'xesam:artist',"Stai ascoltando")
                                        title=track.get(u'xesam:title',"Musica no stop")
                                        start=now-timedelta(microseconds=position)
                                        end=start+timedelta(microseconds=int(track.get(u'mpris:length',None)))
                                        length=timedelta(microseconds=int(track.get(u'mpris:length',None)))


                    except:
                        logging.error("Error with mpris2 interface")
                        uris = get_players_uri(pattern=".",busaddress=autoradio.settings.busaddressplayer)

                        if len(uris) >0 :
                            uri=uris[0]

                            if autoradio.settings.busaddressplayer is None:
                                bus = dbus.SessionBus()
                            else:
                                bus =dbus.bus.BusConnection(autoradio.settings.busaddressplayer)
                                mp2 = MediaPlayer2(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus})
                                play = Player(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus})

                else:
                    title=program_title
                    artist=note
                    # if description is missed set it from program subtype
                    if (artist is None or artist == ""): artist = subtype
                    onair="program"
                    start=pdatetime_start
                    end=pdatetime_end
                    length=pdatetime_end-pdatetime_start
                    update=True

            # check for next program message
            if (pdatetime_start <= (now+nexttimeadvice) and pdatetime_end > (now+nexttimeadvice)):
                logging.info(f"--> next {note} : {program_title} : {type} : {subtype}")
                if (code == "5" or code == "13f"):
                    logging.info("--> next skip spot and playlist for next program")
                    next_artist=None
                    next_title=None
                else:
                    next_artist="Tra poco"
                    next_title=program_title

        logging.info(f"ELABORATE {update} ; {onair} ; {artist} ; {title} ; {start} ; {end} ; {length}")

        if (update and title != current_title_log):
            metatracelogger.info(f"{onair};{artist};{title};{start};{end};{length}")
            current_title_log=title

        if (spare and next_title is not None and next_title != title):
            logging.info(f"NEXT   {next_artist};{next_title};{start};{end};{length}")
            get_dict={ 'mount' : "/rcf.ogg", 'mode' : 'updinfo', 'title' : next_title, 'artist' : next_artist}
            get_param= urllib.parse.urlencode(get_dict)
            url = autoradio.settings.icecastapiurlautoradiometatrace+"?"+get_param
            response = requests.get(url)
            logging.info(response.text)
            next_artist=None
            next_title=None
            current_title=next_title
            spare = False
            last_message_is_next=True

        elif (update and title is not None and title != current_title):
            logging.info(f"CURRENT {onair};{artist};{title};{start};{end};{length}")
            get_dict={ 'mount' : "/rcf.ogg", 'mode' : 'updinfo', 'title' : title, 'artist' : artist}
            get_param= urllib.parse.urlencode(get_dict)
            url = autoradio.settings.icecastapiurlautoradiometatrace+"?"+get_param
            response = requests.get(url)
            logging.info(response.text)
            current_title=title
            spare = True
            
        if (update and end is not None):
            delay=end-(now+nexttimeadvice)
            if (delay > 2*timestep and not last_message_is_next):
                logging.info("sleep {} seconds".format(delay.total_seconds()))
                time.sleep(delay.total_seconds())
        #logging.info("sleep {} seconds".format(timestep.total_seconds()))
        time.sleep(timestep.total_seconds())


if __name__ == '__main__':

    import sys, os
    metatraced.cwd=os.getcwd()

    # this is a triky for ubuntu and debian that remove /var/run every boot
    # ATTENTION, this should be a security problem
    path=os.path.dirname(autoradio.settings.lockfileweb)
    if (not os.path.lexists(path) and path == "/var/run/autoradio" ):
        os.mkdir(path)
        if (os.getuid() == 0):

            user=autoradio.settings.userweb
            group=autoradio.settings.groupweb
            if user is not None and group is not None:
                from pwd import getpwnam
                from grp import getgrnam
                uid = getpwnam<(user)[2]
                gid = getgrnam(group)[2]
                os.chown(path,uid,gid)

    if metatraced.service():
        sys.stdout.write("Autoradioweb version "+_version_+"\n")
        sys.stdout.write("Daemon started with pid %d\n" % os.getpid())
        sys.stdout.write("Daemon stdout output\n")
        sys.stderr.write("Daemon stderr output\n")

        sys.exit(main())  # (this code was run as script)
