#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# This file is part of the Librem 5 Get Package Info tool.
# Display information about installed packages.

# Copyright (C) 2019 Purism SPC
# SPDX-License-Identifier: GPL-3.0+
# Author: David Boddie <david.boddie@puri.sm>

import gi
import os

gi.require_version('Gtk', '3.0')

from gi.repository import GLib, Gtk

from .package_info import Worker


class Application(Gtk.Application):

    def __init__(self):
        super().__init__(application_id='librem5_package_info_tool')
        GLib.set_application_name('Librem 5 Package Information')
        GLib.set_prgname('librem5_package_info_tool')

        self.timeout_id = None
        self.lines = []
        self.output_dir = os.path.join(os.getenv('HOME'), '.local', 'share',
                                       'librem5_package_info_tool')

    def do_activate(self):
        window = Gtk.ApplicationWindow(application=self)
        window.set_icon_name('librem5_package_info_tool')

        header = Gtk.HeaderBar(title=_('Librem 5 Package Information'),
                               show_close_button=True)
        window.set_titlebar(header)

        self.layout = Gtk.Box(orientation='vertical', margin=8, spacing=12)

        if os.path.exists(os.path.join(self.output_dir, 'index.html')):

            question_label = Gtk.Label()
            question_label.set_markup(_('<b>Existing information is available.</b>'))
            view_button = Gtk.Button(
                label=_('View existing information'), halign=Gtk.Align.CENTER)
            view_button.connect('clicked', self.open_docs)
            list_button = Gtk.Button(
                label=_('Generate new information'), halign=Gtk.Align.CENTER)
            list_button.connect('clicked', self.generate_new_info)

            self.question_layout = Gtk.Box(orientation='vertical', margin=8,
                                           spacing=12)
            self.question_layout.add(question_label)
            self.question_layout.add(view_button)
            self.question_layout.add(list_button)
            self.layout.add(self.question_layout)

        else:
            self.start_listing()

        window.add(self.layout)
        window.set_default_size(360, 720)
        window.show_all()

    def generate_new_info(self, *args):

        self.question_layout.hide()
        self.start_listing()

    def start_listing(self):

        layout = Gtk.Box(orientation='vertical', margin=8, spacing=12)
        self.layout.add(layout)

        self.label = Gtk.Label(hexpand=True, hexpand_set=True, ellipsize=True)
        self.label.set_xalign(0.0)

        try:
            if not os.path.exists(self.output_dir):
                os.mkdir(self.output_dir)

            self.progress = Gtk.ProgressBar(show_text=True)
            layout.add(self.progress)
            self.label.set_text(_('Finding package information'))
            self.label.set_justify(Gtk.Justification.LEFT)

            # Get a list of installed packages.
            self.get_installed_packages()

        except OSError:
            self.label.set_text(_('Failed to initialize.\nPlease see '
                'https://docs.puri.sm/Librem_5.html for information about '
                'packages.'))

        layout.add(self.label)
        layout.show_all()

    def get_installed_packages(self):

        self.worker = Worker('/', self.output_dir)

        self.lines.append(_('Reading package sources'))
        self.update_label()

        self.state = 'sources'
        self.iter = self.worker.read_sources()
        self.timeout_id = GLib.idle_add(self.timeout, None)

    def timeout(self, user_data):

        if self.state == 'sources':
            return self.read_source()
        else:
            return self.list_package()

    def read_source(self):

        try:
            for i in range(250):
                info = self.iter.__next__()
                suite_name, i, total = info
                if self.lines[-1] != suite_name:
                    self.lines.append(suite_name)

            self.progress.set_fraction(i/total)
            self.update_label()

        except StopIteration:

            self.progress.set_fraction(0.0)
            self.state = 'listing'
            self.lines = [_('Listing packages')]
            self.lines.append('')
            self.update_label()
            self.iter = self.worker.list_packages()

        return True

    def list_package(self):

        try:
            for i in range(10):
                name, i, total = self.iter.__next__()
                self.lines[-1] = name

            self.progress.set_fraction(i/total)
            self.update_label()

        except StopIteration:
            self.lines = []
            self.update_label()
            self.progress.set_fraction(1.0)

            self.button = Gtk.Button(label=_('Open Package List'),
                                     halign=Gtk.Align.CENTER)
            self.button.connect('clicked', self.open_docs)
            self.layout.add(self.button)
            self.button.show()

            return False

        return True

    def update_label(self):
        self.label.set_text('\n'.join(self.lines))

    def open_docs(self, *args):
        os.system('gnome-www-browser ' + os.path.join(self.output_dir, 'index.html') + '&')
        self.quit()
