/* aspam-window.c
 *
 * Copyright 2021-2022 Chris Talbot
 *
 * 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/>.
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

#include "config.h"
#include "aspam-settings.h"
#include "aspam-window.h"
#include "aspam-pattern-row.h"

struct _ASpamWindow
{
  AdwApplicationWindow  parent_instance;

  /* Widgets */
  GtkWidget   *header_bar;
  GtkWidget   *enable_aspam_switch;
  GtkWidget   *silence_switch;
  GtkWidget   *allow_callback_switch;
  GtkWidget   *callback_timeout_text;
  GtkWidget   *callback_timeout_text_buffer;
  GtkWidget   *allow_blocked_numbers_switch;
  GtkWidget   *blacklist_switch;
  GtkWidget   *new_whitelist;
  GtkWidget   *new_whitelist_text;
  GtkWidget   *new_whitelist_text_buffer;
  GtkWidget   *new_whitelist_button;
  GtkWidget   *pref_page;

};

G_DEFINE_TYPE (ASpamWindow, aspam_window, ADW_TYPE_APPLICATION_WINDOW)

static void
new_whitelist_text_buffer_changed_cb (ASpamWindow *self)
{
  ASpamSettings *settings;
  const char *timeout_string;

  settings = aspam_settings_get_default ();
  timeout_string = gtk_entry_buffer_get_text (GTK_ENTRY_BUFFER (self->new_whitelist_text_buffer));

  if (!timeout_string || !*timeout_string)
    gtk_widget_set_sensitive (self->new_whitelist_button, FALSE);
  else
    gtk_widget_set_sensitive (self->new_whitelist_button, TRUE);

  if (!aspam_settings_get_enable_aspamclient (settings))
    gtk_widget_set_sensitive (self->new_whitelist_button, FALSE);

}

static void
aspam_window_set_swtich_sensitivity (ASpamWindow *self)
{
  ASpamSettings *settings;
  settings = aspam_settings_get_default ();

  gtk_widget_set_sensitive (self->allow_callback_switch,
                            aspam_settings_get_enable_aspamclient (settings));
  gtk_widget_set_sensitive (self->allow_blocked_numbers_switch,
                            aspam_settings_get_enable_aspamclient (settings));
  gtk_widget_set_sensitive (self->silence_switch,
                            aspam_settings_get_enable_aspamclient (settings));
  gtk_widget_set_sensitive (self->blacklist_switch,
                            aspam_settings_get_enable_aspamclient (settings));
  gtk_widget_set_sensitive (self->callback_timeout_text,
                            aspam_settings_get_enable_aspamclient (settings));
  gtk_widget_set_sensitive (self->new_whitelist_text,
                            aspam_settings_get_enable_aspamclient (settings));

  new_whitelist_text_buffer_changed_cb (self);
}

static void
aspam_window_window_populate (ASpamWindow *self)
{
  g_autofree char *callback_timeout_string = NULL;
  ASpamSettings *settings;
  guint64 callback_timeout;
  guint match_list_length;
  char **match_list;
  g_assert (ASPAM_IS_WINDOW (self));
  settings = aspam_settings_get_default ();

  gtk_switch_set_active (GTK_SWITCH (self->enable_aspam_switch),
                         aspam_settings_get_enable_aspamclient (settings));
  gtk_switch_set_active (GTK_SWITCH (self->allow_callback_switch),
                         aspam_settings_get_allow_callback (settings));
  gtk_switch_set_active (GTK_SWITCH (self->allow_blocked_numbers_switch),
                         aspam_settings_get_allow_blocked_numbers (settings));
  gtk_switch_set_active (GTK_SWITCH (self->silence_switch),
                         aspam_settings_get_silence (settings));
  gtk_switch_set_active (GTK_SWITCH (self->blacklist_switch),
                         aspam_settings_get_blacklist (settings));

  aspam_window_set_swtich_sensitivity (self);

  gtk_entry_buffer_set_text (GTK_ENTRY_BUFFER (self->new_whitelist_text_buffer), "", -1);
  callback_timeout = aspam_settings_get_callback_timeout (settings);
  callback_timeout_string = g_strdup_printf ("%" G_GINT64_FORMAT, callback_timeout);

  gtk_entry_buffer_set_text (GTK_ENTRY_BUFFER (self->callback_timeout_text_buffer),
                             callback_timeout_string, -1);

  match_list = aspam_settings_get_match_list (settings);

  match_list_length = g_strv_length (match_list);

  for (guint i = 0; i < match_list_length; i++)
    {
      ASpamPatternRow *new_row;

      if (!*match_list[i])
        continue;

      new_row = aspam_pattern_row_new ();

      adw_preferences_group_add (ADW_PREFERENCES_GROUP (self->new_whitelist),
                                 GTK_WIDGET (new_row));

      adw_action_row_set_subtitle (ADW_ACTION_ROW (new_row),
                                   match_list[i]);
    }
}

static gboolean
enable_aspam_switch_flipped_cb (ASpamWindow *self)
{
  ASpamSettings *settings;
  gboolean enable_aspam;

  g_assert (ASPAM_IS_WINDOW (self));
  settings = aspam_settings_get_default ();
  enable_aspam = gtk_switch_get_active (GTK_SWITCH (self->enable_aspam_switch));
  aspam_settings_set_enable_aspamclient (settings, enable_aspam);

  aspam_window_set_swtich_sensitivity (self);

  return FALSE;
}

static gboolean
silence_switch_flipped_cb (ASpamWindow *self)
{
  ASpamSettings *settings;
  gboolean enable_silence;

  g_assert (ASPAM_IS_WINDOW (self));
  settings = aspam_settings_get_default ();
  enable_silence = gtk_switch_get_active (GTK_SWITCH (self->silence_switch));
  aspam_settings_set_silence (settings, enable_silence);
  return FALSE;
}

static gboolean
allow_callback_switch_flipped_cb (ASpamWindow *self)
{
  ASpamSettings *settings;
  gboolean allow_callback;

  g_assert (ASPAM_IS_WINDOW (self));
  settings = aspam_settings_get_default ();
  allow_callback = gtk_switch_get_active (GTK_SWITCH (self->allow_callback_switch));
  aspam_settings_set_allow_callback (settings, allow_callback);
  return FALSE;
}

static gboolean
blacklist_switch_flipped_cb (ASpamWindow *self)
{
  ASpamSettings *settings;
  gboolean blacklist;

  g_assert (ASPAM_IS_WINDOW (self));
  settings = aspam_settings_get_default ();
  blacklist = gtk_switch_get_active (GTK_SWITCH (self->blacklist_switch));
  aspam_settings_set_blacklist (settings, blacklist);
  return FALSE;
}

static gboolean
allow_blocked_numbers_switch_flipped_cb (ASpamWindow *self)
{
  ASpamSettings *settings;
  gboolean allow_blocked_numbers;

  g_assert (ASPAM_IS_WINDOW (self));
  settings = aspam_settings_get_default ();
  allow_blocked_numbers = gtk_switch_get_active (GTK_SWITCH (self->allow_blocked_numbers_switch));
  aspam_settings_set_allow_blocked_numbers (settings, allow_blocked_numbers);
  return FALSE;
}

static void
callback_timeout_buffer_changed_cb (ASpamWindow *self)
{
  g_autoptr(GError) error = NULL;
  g_autofree char *callback_timeout_string = NULL;
  ASpamSettings *settings;
  const char *timeout_string;
  guint64 new_timeout;
  guint64 callback_timeout;

  g_assert (ASPAM_IS_WINDOW (self));
  settings = aspam_settings_get_default ();

  timeout_string = gtk_entry_buffer_get_text (GTK_ENTRY_BUFFER (self->callback_timeout_text_buffer));

  g_ascii_string_to_unsigned (timeout_string, 10, 0, 9999, &new_timeout, &error);

  if (error) {
    g_warning ("Error converting string to unsigned 64: %s", error->message);
    return;
  }

  callback_timeout = aspam_settings_get_callback_timeout (settings);

  if (new_timeout == callback_timeout)
    return;

  aspam_settings_set_callback_timeout (settings, new_timeout);
}

static void
new_whitelist_button_clicked_cb (ASpamWindow *self)
{
  g_autoptr(GError) error = NULL;
  ASpamSettings *settings;
  const char *new_pattern = "";
  ASpamPatternRow *new_row;
  g_assert (ASPAM_IS_WINDOW (self));
  settings = aspam_settings_get_default ();

  new_pattern = gtk_entry_buffer_get_text (GTK_ENTRY_BUFFER (self->new_whitelist_text_buffer));

  if (!*new_pattern)
    {
      g_debug ("Empty string");
      return;
    }

  new_row = aspam_pattern_row_new ();
  adw_preferences_group_add (ADW_PREFERENCES_GROUP (self->new_whitelist),
                             GTK_WIDGET (new_row));


  adw_action_row_set_subtitle (ADW_ACTION_ROW (new_row),
                               new_pattern);

  aspam_settings_add_match (settings,
                            new_pattern);

  gtk_entry_buffer_set_text (GTK_ENTRY_BUFFER (self->new_whitelist_text_buffer), "", -1);
}

void
aspam_window_reset (ASpamWindow *self)
{
  g_autofree char *callback_timeout_string = NULL;
  ASpamSettings *settings;
  guint64 callback_timeout;
  g_assert (ASPAM_IS_WINDOW (self));
  /* Reset the window if this is a daemon */

  settings = aspam_settings_get_default ();
  callback_timeout = aspam_settings_get_callback_timeout (settings);
  callback_timeout_string = g_strdup_printf ("%" G_GINT64_FORMAT, callback_timeout);

  gtk_entry_buffer_set_text (GTK_ENTRY_BUFFER (self->new_whitelist_text_buffer), "", -1);
  gtk_entry_buffer_set_text (GTK_ENTRY_BUFFER (self->callback_timeout_text_buffer),
                             callback_timeout_string, -1);

  /* TODO: adw_preferences_page_scroll_to_top () is added in libadwaita 1.3 */
  //adw_preferences_page_scroll_to_top (self->pref_page)
}

static void
aspam_window_class_init (ASpamWindowClass *klass)
{
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

  gtk_widget_class_set_template_from_resource (widget_class, "/org/kop316/antispam/ui/aspam-window.ui");
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, header_bar);
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, pref_page);
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, enable_aspam_switch);
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, silence_switch);
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, allow_callback_switch);
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, blacklist_switch);
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, callback_timeout_text);
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, callback_timeout_text_buffer);
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, allow_blocked_numbers_switch);
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, new_whitelist);
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, new_whitelist_text);
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, new_whitelist_text_buffer);
  gtk_widget_class_bind_template_child (widget_class, ASpamWindow, new_whitelist_button);

  gtk_widget_class_bind_template_callback (widget_class, allow_callback_switch_flipped_cb);
  gtk_widget_class_bind_template_callback (widget_class, silence_switch_flipped_cb);
  gtk_widget_class_bind_template_callback (widget_class, callback_timeout_buffer_changed_cb);
  gtk_widget_class_bind_template_callback (widget_class, new_whitelist_text_buffer_changed_cb);
  gtk_widget_class_bind_template_callback (widget_class, new_whitelist_button_clicked_cb);
  gtk_widget_class_bind_template_callback (widget_class, enable_aspam_switch_flipped_cb);
  gtk_widget_class_bind_template_callback (widget_class, allow_blocked_numbers_switch_flipped_cb);
  gtk_widget_class_bind_template_callback (widget_class, blacklist_switch_flipped_cb);

}

static void
aspam_window_init (ASpamWindow *self)
{
  gtk_widget_init_template (GTK_WIDGET (self));

  aspam_window_window_populate (self);
}
