/*
     This file is part of anastasis-gtk.
     Copyright (C) 2021 Anastasis SARL

     Anastasis 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, or (at your
     option) any later version.

     Anastasis 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 Anastasis; see the file COPYING.  If not, write to the
     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     Boston, MA 02110-1301, USA.
*/

/**
 * @file src/anastasis/anastasis-gtk_print.c
 * @brief Implementation of the "Save as" button for the user attributes
 * @author Christian Grothoff
 */
#include <gnunet/gnunet_util_lib.h>
#include "anastasis_gtk_util.h"
#include "anastasis-gtk_attributes.h"
#include "anastasis-gtk_helper.h"
#include <jansson.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "print.h"


/**
 * Generate PDF of the user's personal attributes
 * and output it to @a filename.
 *
 * @param parent_window the parent window of the button
 * @param filename where to store the result
 */
static void
print_to_file (GtkWindow *parent_window,
               const char *filename)
{
  json_t *attr;
  json_t *attrs;
  json_t *uattrs;
  int ret;
  json_t *av;
  json_t *ra;
  const char *key;

  ra = json_object_get (AG_redux_state,
                        "required_attributes");
  attr = AG_collect_attributes (false);
  attrs = json_object_get (attr,
                           "identity_attributes");
  /*
     Example for ATTRS is now:
     "full_name": "Max",
     "birthdate": "1980-09-22",
     "sq_number": "4"
  */
  /* Convert JSON key 'full_name' to (possibly translated) version
     of "Full name" using the "required_attributes" data structure
     in 'ra' */
  uattrs = json_object ();
  json_object_foreach (attrs, key, av)
  {
    json_t *pos;
    size_t off;
    bool found = false;

    if (0 == strcmp (key,
                     "application_id"))
      continue; /* not an attribute the user entered */
    json_array_foreach (ra, off, pos)
    {
      const char *name = json_string_value (json_object_get (pos,
                                                             "name"));

      if (NULL == name)
      {
        GNUNET_break (0);
        continue;
      }
      if (0 == strcmp (name,
                       key))
      {
        const char *tkey;
        struct GNUNET_JSON_Specification spec[] = {
          GNUNET_JSON_spec_string ("label",
                                   &tkey),
          GNUNET_JSON_spec_end ()
        };

        if (GNUNET_OK !=
            GNUNET_JSON_parse (pos,
                               spec,
                               NULL, NULL))
        {
          GNUNET_break (0);
          continue;
        }
        found = true;
        GNUNET_break (0 ==
                      json_object_set (uattrs,
                                       dgettext ("anastasis",
                                                 tkey),
                                       av));
      }
    }
    if (! found)
    {
      GNUNET_break (0);
      GNUNET_break (0 ==
                    json_object_set (uattrs,
                                     key,
                                     av));
    }
  }
  json_decref (attr); /* 'attrs' is borrowed from 'attr' */

  /* now convert to PDF */
  ret = AG_print (uattrs,
                  filename);
  json_decref (uattrs);
  if (0 != ret)
  {
    /* report something went wrong; alas, we don't have a good
       error message here (yet)...*/
    GtkAlertDialog *dialog;

    dialog = gtk_alert_dialog_new ("%s",
                                   _ ("Failed to generate PDF file."));
    gtk_alert_dialog_show (dialog,
                           parent_window);
    g_object_unref (dialog);
  }
}


/**
 * Function called once the user picked the file to print to.
 *
 * @param source the file dialog
 * @param res the result of the user's choice
 * @param user_data the window the dialog belongs to
 */
static void
print_dialog_response_cb (GObject *source,
                          GAsyncResult *res,
                          gpointer user_data)
{
  GtkWindow *parent_window = user_data;
  GFile *file;
  char *filename;

  file = gtk_file_dialog_save_finish (GTK_FILE_DIALOG (source),
                                      res,
                                      NULL);
  if (NULL == file)
    return; /* user aborted */
  filename = ANASTASIS_GTK_file_get_path_utf8 (file);
  g_object_unref (file);
  if (NULL == filename)
    return;
  print_to_file (parent_window,
                 filename);
  GNUNET_free (filename);
}


/**
 * The user clicked the 'save as' button to save their personal
 * details. Try to save them as a PDF.
 *
 * @param button the button that triggered printing
 * @param user_data the builder for the dialog
 */
void
anastasis_gtk_print_details_button_clicked_cb (GtkWidget *button,
                                               gpointer user_data)
{
  GtkFileDialog *dialog;
  GtkWindow *parent_window;
  GtkRoot *top;

  (void) user_data;
  top = gtk_widget_get_root (button);
  if (GTK_IS_WINDOW (top))
  {
    parent_window = GTK_WINDOW (top);
  }
  else
  {
    GNUNET_break (0);
    parent_window = NULL;
  }
  dialog = gtk_file_dialog_new ();
  gtk_file_dialog_set_title (dialog,
                             _ ("Save Personal Details to PDF file"));
  gtk_file_dialog_set_initial_name (dialog,
                                    _ ("anastasis-personal-details.pdf"));
  gtk_file_dialog_save (dialog,
                        parent_window,
                        NULL,
                        &print_dialog_response_cb,
                        parent_window);
  g_object_unref (dialog);
}
