#!/usr/bin/env python

import pyalpm
import pycman
from gi.repository import Notify as notify
from gi.repository import Gtk as gtk
from gi.repository import GLib as glib
import os
import traceback

PACMAN_CONFIG = "/etc/pacman.conf"


def check_user():
    if os.getuid() is not 0:
        raise Exception("User must be root to use alpm!")


def update_dbs(handle):
    print("Updating dbs")
    for db in handle.get_syncdbs():
        db.update(False)

COLUMN_HEADERS = ["Package", "New Version"]
DIALOG_DISPLAYED = False


def display_list(notification, action, packages):
    try:
        global DIALOG_DISPLAYED
        DIALOG_DISPLAYED = True
        dialog = gtk.Dialog()
        dialog.set_title("Avaialble Updates")
        dialog.set_modal(True)
        dialog.add_button(button_text="OK", response_id=gtk.ResponseType.OK)
        dialog.connect("response", lambda widget, response_id: gtk.main_quit())

        content_area = dialog.get_content_area()
        list_store = gtk.ListStore(str, str)
        for i in packages:
            list_store.append(i)

        disp_widget = gtk.TreeView(model=list_store)
        disp_widget.get_selection().set_mode(gtk.SelectionMode.NONE)
        disp_widget.set_hscroll_policy(gtk.ScrollablePolicy.MINIMUM)

        for i in range(len(COLUMN_HEADERS)):
            cell = gtk.CellRendererText()
            col = gtk.TreeViewColumn(COLUMN_HEADERS[i], cell, text=i)
            disp_widget.append_column(col)

        scrolled = gtk.ScrolledWindow(None, None)
        scrolled.add(disp_widget)
        content_area.pack_start(scrolled, True, True, 0)
        scrolled.set_min_content_width(disp_widget.get_preferred_width()[1]) # Min width
        scrolled.set_min_content_height((disp_widget.get_preferred_height()[1] / float(len(packages))) * 10)
        dialog.show_all()
    except Exception:
        traceback.print_exc()
        gtk.main_quit()
        DIALOG_DISPLAYED = False


def show_notification(transaction):
    packages = [(i.name, i.version) for i in transaction.to_add]
    if len(packages) > 0:
        note = notify.Notification.new("Out of date", "There are " + str(len(packages)) + " updates available!", "dialog-warning")
        note.set_urgency(notify.Urgency.CRITICAL)
        note.add_action("view-packages", "View packages with available updates", display_list, packages, None)
        note.connect("closed", close_if_not_update_button)
        note.show()
        gtk.main()
    else:
        note = notify.Notification.new("Up to date", "Congratulations, you're up to date!", None)
        note.set_urgency(notify.Urgency.LOW)
        note.show()

def close_if_not_update_button(note):
    print("Notification closed")
    if not DIALOG_DISPLAYED:
        gtk.main_quit()


def main():
    transaction = None
    try:
        notify.init("PacUpdater")
        #check_user()
        handle = pycman.config.init_with_config(PACMAN_CONFIG)

        transaction = handle.init_transaction(nolock=True) # Flag NOLOCK (don't create the lock)

        # update_dbs(handle)
        transaction.sysupgrade(False)
        show_notification(transaction)
    except pyalpm.error:
        traceback.print_exc()
    except Exception as e:
        print(e)

    try:
        if transaction:
            transaction.release()
    except pyalpm.error:
        pass
        

if __name__ == "__main__":
    main()
