/* aspam-application.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 "version.h"

#include "aspam-application.h"
#include "aspam-client.h"
#include "aspam-settings.h"
#include "aspam-window.h"

struct _ASpamApplication
{
  AdwApplication parent_instance;
  gboolean        daemon;
  gboolean        daemon_running;
  GtkWindow      *main_window;
  gboolean        app_debug;

  ASpamSettings  *settings;
  ASpamClient    *client;
};

G_DEFINE_TYPE (ASpamApplication, aspam_application, ADW_TYPE_APPLICATION)

ASpamApplication *
aspam_application_new (const char        *application_id,
                       GApplicationFlags  flags)
{
  g_return_val_if_fail (application_id != NULL, NULL);

  return g_object_new (ASPAM_TYPE_APPLICATION,
                       "application-id", application_id,
                       "flags", flags,
                       NULL);
}

static int
aspam_handle_local_options (GApplication *application,
                            GVariantDict *options)
{
  ASpamApplication *self = (ASpamApplication *)application;
  if (g_variant_dict_contains (options, "version"))
    {
      g_print ("%s, git version: %s\n", PACKAGE_VERSION, PACKAGE_VCS_VERSION);
      return 0;
    }

  if (g_variant_dict_contains (options, "debug"))
    {
      g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
      self->app_debug = TRUE;
    }

  self->daemon = FALSE;
  self->app_debug = FALSE;
  if (g_variant_dict_contains (options, "daemon"))
    {
      /* Hold application only the first time daemon mode is set */
      if (!self->daemon)
        g_application_hold (application);

      self->daemon = TRUE;
      g_debug ("Application marked as daemon");
    }

  return -1;
}

static void
aspam_application_startup (GApplication *application)
{
  ASpamApplication *self = (ASpamApplication *)application;

  g_info ("%s %s, git version: %s", PACKAGE_NAME, PACKAGE_VERSION, PACKAGE_VCS_VERSION);

  G_APPLICATION_CLASS (aspam_application_parent_class)->startup (application);

  g_set_application_name ("Anti-Spam");
  gtk_window_set_default_icon_name (PACKAGE_ID);

  self->settings = aspam_settings_get_default ();
  self->client = aspam_client_get_default ();
}

static gboolean
on_widget_deleted (GtkWidget *widget,
                   GdkEvent  *event,
                   gpointer   data)
{
  /* Reset the window when closing */
  aspam_window_reset (ASPAM_WINDOW (widget));

  return FALSE;
}

static void
aspam_application_activate (GApplication *app)
{
  ASpamApplication *self = (ASpamApplication *)app;

  if (!self->main_window)
    {
      self->main_window = g_object_new (ASPAM_TYPE_WINDOW, "application", app, NULL);
      g_object_add_weak_pointer (G_OBJECT (self->main_window), (gpointer *)&self->main_window);

      g_signal_connect (G_OBJECT (self->main_window),
                        "close_request", G_CALLBACK (on_widget_deleted), app);
    }

  if ((!self->daemon && !self->daemon_running) || (self->daemon_running))
    gtk_window_present (GTK_WINDOW (self->main_window));
  else {
      self->daemon_running = TRUE;
      gtk_window_set_hide_on_close (GTK_WINDOW (self->main_window), self->daemon_running);
    }
}

static void
aspam_application_class_init (ASpamApplicationClass *klass)
{
  GApplicationClass *app_class = G_APPLICATION_CLASS (klass);

  app_class->handle_local_options = aspam_handle_local_options;
  app_class->startup = aspam_application_startup;
  app_class->activate = aspam_application_activate;
}

static void
aspam_application_about_action (GSimpleAction *action,
                                GVariant      *parameter,
                                gpointer       user_data)
{
  ASpamApplication *self = user_data;
  GtkWindow *window = NULL;

  const char *authors[] = {
    "Chris Talbot https://www.gitlab.com/kop316/",
    NULL
  };

  g_assert (ASPAM_IS_APPLICATION (self));

  window = gtk_application_get_active_window (GTK_APPLICATION (self));

  gtk_show_about_dialog (GTK_WINDOW (window),
                         "website", "https://gitlab.com/kop316/phosh-antispam",
                         "version", PACKAGE_VCS_VERSION,
                         "copyright", "Copyright © 2021 Chris Talbot",
                         "license-type", GTK_LICENSE_GPL_3_0,
                         "authors", authors,
                         "logo-icon-name", PACKAGE_ID,
                         NULL);
}

static GOptionEntry cmd_options[] = {
  {
    "daemon", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, NULL,
    ("Whether to present the main window on startup"),
    NULL
  },
  { "debug", 'd', 0, G_OPTION_ARG_NONE, G_OPTION_ARG_NONE,
    "Enable debugging output"},
  {
    "version", 'v', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, NULL,
    ("Show release version"), NULL
  },
  { NULL }
};


static const GActionEntry app_actions[] = {
  { "about", aspam_application_about_action },
};

static void
aspam_application_init (ASpamApplication *self)
{
  g_action_map_add_action_entries (G_ACTION_MAP (self),
                                   app_actions,
                                   G_N_ELEMENTS (app_actions),
                                   self);
  g_application_add_main_option_entries (G_APPLICATION (self), cmd_options);
}
