# Copyright (c) 2014-2018 Cedric Bellegarde <cedric.bellegarde@adishatz.org>
# 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 3 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, see <http://www.gnu.org/licenses/>.

from gi.repository import Gtk, Gdk, GLib, Gio

from gettext import gettext as _

from passbook.define import App
from passbook.helper_secrets import SecretsHelper
from passbook.logger import Logger


# Broken, signals from headerbar not working
# @Gtk.Template.from_resource
class AddCollectionDialog:
    """
        Dialog to add a new collection
    """

    # __gtype_name__ = "AddCollectionDialog"
    # name_entry = Gtk.Template.Child()
    # password_entry = Gtk.Template.Child()
    # headerbar = Gtk.Template.Child()

    def __init__(self):
        """
            Init dialog
        """
        builder = Gtk.Builder()
        builder.add_from_resource(
            "/org/gnome/Passbook/AddCollectionDialog.ui")
        builder.connect_signals(self)
        self.__dialog = builder.get_object("dialog")
        self.__stack = builder.get_object("stack")
        self.__new_button = builder.get_object("new_button")
        self.__name_entry = builder.get_object("name_entry")
        self.__filechooser = builder.get_object("filechooser")
        self.__warning = builder.get_object("warning")
        self.__filter_keepass = Gtk.FileFilter()
        self.__filter_keepass.set_name("Keepass kdbx")
        self.__filter_keepass.add_pattern("*.kdbx")
        builder.get_object("name").set_active(True)
        self.__create_button = builder.get_object("create_button")
        self.__dialog.set_transient_for(App().window)
        if not App().keepass:
            builder.get_object("keepass").hide()
            self.__filechooser.hide()
            self.__new_button.hide()

    def run(self):
        """
            Run dialog
        """
        self.__dialog.run()
        self.__dialog.destroy()

#######################
# PROTECTED           #
#######################
    def _on_collection_type_toggled(self, button):
        """
            Update widgets state
            @param button as Gtk.ToggleButton
        """
        if button.get_active():
            name = button.get_name()
            keepass_selected = name == "keepass"
            self.__name_entry.set_sensitive(name == "name")
            self.__filechooser.set_sensitive(keepass_selected)
            self.__new_button.set_sensitive(keepass_selected)
            if keepass_selected and\
                    not App().settings.get_value("keepass-uris"):
                self.__warning.show()
                self.__stack.set_visible_child_name("password_safe")

    def _on_key_release_event(self, entry, event):
        """
            Update button visibility and set default response on Enter
            @param entry as Gtk.Entry
            @param event as Gdk.Event
        """
        if event.keyval in [Gdk.KEY_Return, Gdk.KEY_KP_Enter]:
            if self.__create_button.get_sensitive():
                self.__dialog.response(Gtk.ResponseType.OK)
        else:
            sensitive = self.__name_entry.get_text()
            self.__create_button.set_sensitive(sensitive)

    def _on_filechooser_file_set(self, filechooser):
        """
            Update button visibility
            @param filechooser as Gtk.FileChooserButton
        """
        self.__create_button.set_sensitive(True)

    def _on_new_keepass_button_clicked(self, button):
        """
            Change filechooser type and show it
            @param button as Gtk.Button
        """
        filechooser = Gtk.FileChooserNative.new(_("New Keepass file"),
                                                self.__dialog,
                                                Gtk.FileChooserAction.SAVE,
                                                _("Create"),
                                                _("Cancel"))
        filechooser.connect("response", self._on_response)
        filechooser.add_filter(self.__filter_keepass)
        filechooser.run()

    def _on_response(self, dialog, response_id):
        """
            Add collection
            @param dialog as Gtk.FileChooser
            @param response_id as int
        """
        if response_id in [Gtk.ResponseType.CANCEL,
                           Gtk.ResponseType.DELETE_EVENT]:
            return
        save = dialog != self.__dialog
        if save:
            filechooser = dialog
        else:
            filechooser = self.__filechooser
        if self.__name_entry.get_sensitive():
            name = self.__name_entry.get_text()
            helper = SecretsHelper()
            helper.add_collection(name, self.__on_add_collection)
        else:
            uri = filechooser.get_uri()
            # Create a new db if missing
            is_kdbx = uri.split(".")[-1] == "kdbx"
            # Create a new default file
            if save:
                if not is_kdbx:
                    uri += ".kdbx"
                    is_kdbx = True
                f = Gio.File.new_for_uri(uri)
                if not f.query_exists():
                    default = Gio.File.new_for_uri(
                            "resource:///org/gnome/Passbook/default.kdbx")
                    default.copy(f, Gio.FileCopyFlags.OVERWRITE)
            if is_kdbx:
                uris = list(App().settings.get_value("keepass-uris"))
                if uri not in uris:
                    uris.append(uri)
                App().settings.set_value("keepass-uris",
                                         GLib.Variant("as", uris))
                App().window.add_keepass_collection(uri)
            else:
                Logger.error("Invalid file extension !")
        if dialog != self.__dialog:
            self.__dialog.destroy()

    def _on_cancel_clicked(self, button):
        """
            Close dialog
            @param button as Gtk.Button
        """
        self.__dialog.response(Gtk.ResponseType.CANCEL)

    def _on_create_clicked(self, button):
        """
            Create collection
            @param button as Gtk.Button
        """
        self.__dialog.response(Gtk.ResponseType.OK)

    def _on_password_safe_button_clicked(self, button):
        """
            Switch to default child
            @param button as Gtk.Button
        """
        self.__stack.set_visible_child_name("default")

#######################
# PRIVATE             #
#######################
    def __on_add_collection(self, collection):
        """
            Set password on new collection
            @param collection as Secret.Collection
        """
        App().window.add_collection(collection)
