#!/usr/bin/env python3
import os
from os.path import dirname, abspath
import json
import subprocess
import sys
import webbrowser

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
try:
    gi.require_version('AppIndicator3', '0.1')
    from gi.repository import AppIndicator3 as appindicator
except:
    appindicator = None


base = dirname(dirname(dirname(abspath(__file__))))
icon = os.path.join(base, 'openmedialibrary/static/png/oml.png')
title = "Open Media Library"
ctl = base + '/ctl'


class OMLIcon:
    menu = None
    icon = None
    indicator = None

    def __init__(self, autostart=False):
        self.autostart = autostart
        self.create_pid()
        if appindicator:
            self.indicator = appindicator.Indicator.new("OML", icon,
                appindicator.IndicatorCategory.APPLICATION_STATUS)
            self.indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
            self.menu = self.get_menu()
            self.indicator.set_menu(self.menu)
        else:
            self.icon = Gtk.StatusIcon()
            self.icon.set_from_file(icon)
            self.icon.set_title(title)
            self.icon.connect("activate", self._click)
            self.icon.connect("popup-menu", self._click)
        subprocess.Popen([ctl, 'start'], close_fds=True, preexec_fn=preexec)
        if not self.autostart:
            GLib.timeout_add_seconds(1, self._open, None)
        GLib.timeout_add_seconds(60, self._check, None)

    def _check(self, *args, **kwargs):
        pid = os.path.join(base, 'data', 'openmedialibrary.pid')
        if os.path.exists(pid):
            GLib.timeout_add_seconds(60, self._check, None)
        else:
            self._quit(None)

    def create_pid(self):
        pid = self.get_pid()
        if pid:
            with open(pid, 'w') as fd:
                fd.write('%s' % os.getpid())

    @classmethod
    def remove_pid(cls):
        pid = cls.get_pid()
        if pid and os.path.exists(pid):
            os.unlink(pid)

    @classmethod
    def get_pid(cls):
        run = '/run/user/%s' % os.getuid()
        if os.path.exists(run):
            oml = os.path.join(run, 'openmedialibrary')
            if not os.path.exists(oml):
                os.makedirs(oml)
            pid = os.path.join(oml, 'pid')
        else:
            pid = None
        return pid

    @classmethod
    def is_running(cls):
        pid = cls.get_pid()
        if pid and os.path.exists(pid):
            return True
        else:
            return False

    def get_menu(self):
        menu = Gtk.Menu()
        t = Gtk.MenuItem(label=title)
        t.set_sensitive(False)
        menu.append(t)
        menu.append(Gtk.SeparatorMenuItem())
        about = Gtk.MenuItem(label="Launch")
        about.connect("activate", self._open)
        menu.append(about)
        quit = Gtk.MenuItem(label="Quit")
        quit.connect("activate", self._quit)
        menu.append(quit)
        menu.show_all()
        return menu

    def _click(self, icon, button=None, time=None):
        if self.menu:
            self.menu.destroy()
            self.menu = None
        else:
            self.menu = self.get_menu()
            button = 1
            time = Gtk.get_current_event_time()
            self.menu.popup(None, None, self.icon.position_menu, icon, button, time)

    def _quit(self, q):
        Gtk.main_quit()
        self.stop()

    def stop(self, *args, **kwargs):
        p = subprocess.Popen([ctl, 'stop'], close_fds=True)
        self.menu = None
        self.remove_pid()

    def _open(self, *args):
        self.load()
        self.menu = None

    @classmethod
    def load(cls):
        config = os.path.join(base, 'data', 'server.json')
        default_port = port = 9842
        if os.path.exists(config):
            try:
                with open(config) as fd:
                    config = json.load(fd)
                port = config.get('port', port)
            except:
                pass
        url = 'file://' + base + '/openmedialibrary/static/html/load.html'
        if port != default_port:
            url += '#%s' % port
        webbrowser.open_new_tab(url)

def preexec():  # Don't forward signals.
    os.setpgrp()

if __name__ == '__main__':
    import signal
    autostart = len(sys.argv) > 1 and sys.argv[1] == '--autostart'
    if OMLIcon.is_running():
        OMLIcon.load()
    else:
        oml = OMLIcon(autostart)
        main_loop = GLib.MainLoop()
        try:
            main_loop.run()
        except KeyboardInterrupt:
            oml.stop()