/* gcc $(pkg-config --cflags --libs libgdata goa-1.0 gio-2.0 glib-2.0)
   gdata-upload-delete-copy.c */

#include <gio/gio.h>
#include <glib.h>

#define GOA_API_IS_SUBJECT_TO_CHANGE
#include <gdata/gdata.h>
#include <goa/goa.h>

static void
show_entry (GDataDocumentsService *service, GDataEntry *entry)
{
  GDataLink *link;
  GError *error = NULL;
  GList *authors;
  GList *categories;
  GList *k;
  GList *links = NULL;
  const gchar *document_id;
  const gchar *id;
  const gchar *resource_id;
  const gchar *title;
  const gchar *uri;

  id = gdata_entry_get_id (entry);
  g_message ("id: %s", id);

  g_message ("type: %s", G_OBJECT_TYPE_NAME (entry));

  document_id = gdata_documents_entry_get_document_id (GDATA_DOCUMENTS_ENTRY (entry));
  resource_id = gdata_documents_entry_get_resource_id (GDATA_DOCUMENTS_ENTRY (entry));
  g_message ("document_id: %s, resource_id: %s", document_id, resource_id);

  title = gdata_entry_get_title (entry);
  g_message ("title: %s", title);

  link = gdata_entry_look_up_link (entry, GDATA_LINK_SELF);
  uri = gdata_link_get_uri (link);
  g_message ("self: %s", uri);

  link = gdata_entry_look_up_link (entry, GDATA_LINK_ALTERNATE);
  uri = gdata_link_get_uri (link);
  g_message ("alternate: %s", uri);

  links = gdata_entry_look_up_links (entry, GDATA_LINK_PARENT);
  for (k = links; k != NULL; k = k->next)
    {
      link = GDATA_LINK (k->data);
      uri = gdata_link_get_uri (link);
      g_message ("parent: %s", uri);
    }

  categories = gdata_entry_get_categories (entry);
  for (k = categories; k != NULL; k = k->next)
    {
      GDataCategory *category = GDATA_CATEGORY (k->data);
      const gchar *label;
      const gchar *scheme;
      const gchar *term;

      scheme = gdata_category_get_scheme (category);
      g_message ("scheme: %s", scheme);

      term = gdata_category_get_term (category);
      g_message ("term: %s", term);

      label = gdata_category_get_label (category);
      g_message ("label: %s", label);
    }

  authors = gdata_entry_get_authors (GDATA_ENTRY (entry));
  for (k = authors; k != NULL; k = k->next)
    {
      GDataAuthor *author = GDATA_AUTHOR (k->data);
      const gchar *email;
      const gchar *name;

      email = gdata_author_get_email_address (author);
      name = gdata_author_get_name (author);
      uri = gdata_author_get_uri (author);
      g_message ("email: %s, name: %s, uri: %s", email, name, uri);
    }

 out:
  g_list_free (links);
}

gint
main (void)
{
  GDataAuthorizationDomain *domain;
  GDataDocumentsDocument *document = NULL;
  GDataDocumentsDocument *new_document = NULL;
  GDataDocumentsEntry *copied_document = NULL;
  GDataDocumentsEntry *copied_folder = NULL;
  GDataDocumentsEntry *new_folder = NULL;
  GDataDocumentsFolder *folder = NULL;
  GDataDocumentsService *service = NULL;
  GDataEntry *old_document = NULL;
  GDataEntry *old_folder = NULL;
  GDataEntry *parent = NULL;
  GDataUploadStream *ostream = NULL;
  GError *error = NULL;
  GFile *local_file = NULL;
  GFileInputStream *istream = NULL;
  GList *accounts = NULL;
  GList *l;
  GoaClient *client = NULL;
  const gchar *id;
  const gchar *uri;

  client = goa_client_new_sync (NULL, &error);
  if (error != NULL)
    {
      g_warning ("%s", error->message);
      g_error_free (error);
      goto out;
    }

  accounts = goa_client_get_accounts (client);
  for (l = accounts; l != NULL; l = l->next)
    {
      GoaAccount *account;
      GoaObject *object = GOA_OBJECT (l->data);
      const gchar *provider_type;

      account = goa_object_peek_account (object);
      provider_type = goa_account_get_provider_type (account);

      if (g_strcmp0 (provider_type, "google") == 0)
        {
          GDataGoaAuthorizer *authorizer;

          authorizer = gdata_goa_authorizer_new (object);
          service = gdata_documents_service_new (GDATA_AUTHORIZER (authorizer));
          g_object_unref (authorizer);
        }
    }

  if (service == NULL)
    {
      g_warning ("account not found");
      goto out;
    }

  local_file = g_file_new_for_path ("/home/rishi/Documents/Karty.pdf");

  error = NULL;
  istream = g_file_read (local_file, NULL, &error);
  if (error != NULL)
    {
      g_warning ("read: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  domain = gdata_documents_service_get_primary_authorization_domain ();

  /* a folder: Lil' Sandbox */
  id = "0B9J_DkaiBDRFajM2NmJiWHBrclU";

  error = NULL;
  parent = gdata_service_query_single_entry (GDATA_SERVICE (service),
                                             domain,
                                             id,
                                             NULL,
                                             GDATA_TYPE_DOCUMENTS_FOLDER,
                                             NULL,
                                             &error);
  if (error != NULL)
    {
      g_warning ("query-single-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  show_entry (service, parent);

  g_message ("======");

  folder = gdata_documents_folder_new (NULL);
  gdata_entry_set_title (GDATA_ENTRY (folder), "Playground");

  error = NULL;
  new_folder = gdata_documents_service_add_entry_to_folder (service,
                                                            GDATA_DOCUMENTS_ENTRY (folder),
                                                            GDATA_DOCUMENTS_FOLDER (parent),
                                                            NULL,
                                                            &error);
  if (error != NULL)
    {
      g_warning ("add-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  show_entry (service, GDATA_ENTRY (new_folder));

  g_message ("======");

  uri = gdata_documents_service_get_upload_uri (GDATA_DOCUMENTS_FOLDER (parent));
  g_message ("upload_uri: %s", uri);

  g_message ("======");

  document = gdata_documents_document_new (NULL);
  gdata_entry_set_title (GDATA_ENTRY (document), "Karty");

  error = NULL;
  ostream = gdata_documents_service_upload_document (service,
                                                     document,
                                                     "Karty",
                                                     "application/pdf",
                                                     GDATA_DOCUMENTS_FOLDER (new_folder),
                                                     NULL,
                                                     &error);
  if (error != NULL)
    {
      g_warning ("upload-document: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  error = NULL;
  g_output_stream_splice (G_OUTPUT_STREAM (ostream),
                          G_INPUT_STREAM (istream),
                          G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
                          NULL,
                          &error);
  if (error != NULL)
    {
      g_warning ("splice: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  error = NULL;
  new_document = gdata_documents_service_finish_upload (service, ostream, &error);
  if (error != NULL)
    {
      g_warning ("finish-upload: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  show_entry (service, GDATA_ENTRY (new_document));

  error = NULL;
  gdata_service_delete_entry (GDATA_SERVICE (service), domain, GDATA_ENTRY (new_document), NULL, &error);
  if (error != NULL)
    {
      g_warning ("delete-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  g_message ("======");

  /* a folder: Foo */
  id = "0B9J_DkaiBDRFbGNzNkNOeFpuMjA";

  error = NULL;
  old_folder = gdata_service_query_single_entry (GDATA_SERVICE (service),
                                                 domain,
                                                 id,
                                                 NULL,
                                                 GDATA_TYPE_DOCUMENTS_FOLDER,
                                                 NULL,
                                                 &error);
  if (error != NULL)
    {
      g_warning ("query-single-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  show_entry (service, old_folder);

  g_message ("======");

  error = NULL;
  copied_folder = gdata_documents_service_add_entry_to_folder (service,
                                                               GDATA_DOCUMENTS_ENTRY (old_folder),
                                                               GDATA_DOCUMENTS_FOLDER (new_folder),
                                                               NULL,
                                                               &error);
  /* failure expected */
  if (error != NULL)
    {
      g_warning ("Failed to copy folder: add-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
    }

  g_message ("======");

  /* a native Drive document: Online Content Storage and GNOME */
  id = "1T4Z2q7q_0fa-qdFqIpCQVNYe78RLNS0UqhMRgY1ixGs";

  error = NULL;
  old_document = gdata_service_query_single_entry (GDATA_SERVICE (service),
                                                   domain,
                                                   id,
                                                   NULL,
                                                   GDATA_TYPE_DOCUMENTS_TEXT,
                                                   NULL,
                                                   &error);
  if (error != NULL)
    {
      g_warning ("query-single-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  show_entry (service, old_document);

  g_message ("======");

  error = NULL;
  copied_document = gdata_documents_service_add_entry_to_folder (service,
                                                                 GDATA_DOCUMENTS_ENTRY (old_document),
                                                                 GDATA_DOCUMENTS_FOLDER (new_folder),
                                                                 NULL,
                                                                 &error);
  if (error != NULL)
    {
      g_warning ("add-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  show_entry (service, GDATA_ENTRY (copied_document));

  g_clear_object (&copied_document);
  g_clear_object (&old_document);

  g_message ("======");

  /* a JPEG: sistina.jpg */
  id = "0B9J_DkaiBDRFTnQ0WEhsX2pqQnc";

  error = NULL;
  old_document = gdata_service_query_single_entry (GDATA_SERVICE (service),
                                                   domain,
                                                   id,
                                                   NULL,
                                                   GDATA_TYPE_DOCUMENTS_DOCUMENT,
                                                   NULL,
                                                   &error);
  if (error != NULL)
    {
      g_warning ("query-single-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  show_entry (service, old_document);

  g_message ("======");

  error = NULL;
  copied_document = gdata_documents_service_add_entry_to_folder (service,
                                                                 GDATA_DOCUMENTS_ENTRY (old_document),
                                                                 GDATA_DOCUMENTS_FOLDER (new_folder),
                                                                 NULL,
                                                                 &error);
  if (error != NULL)
    {
      g_warning ("add-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  show_entry (service, GDATA_ENTRY (copied_document));

  g_clear_object (&copied_document);
  g_clear_object (&old_document);

  g_message ("======");

  /* a map: map-of-brno */
  id = "1DIB8fGWAhJvrwYCG2UgVgCOuJPk";

  error = NULL;
  old_document = gdata_service_query_single_entry (GDATA_SERVICE (service),
                                                   domain,
                                                   id,
                                                   NULL,
                                                   GDATA_TYPE_DOCUMENTS_DOCUMENT,
                                                   NULL,
                                                   &error);
  if (error != NULL)
    {
      g_warning ("query-single-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  show_entry (service, old_document);

  g_message ("======");

  error = NULL;
  copied_document = gdata_documents_service_add_entry_to_folder (service,
                                                                 GDATA_DOCUMENTS_ENTRY (old_document),
                                                                 GDATA_DOCUMENTS_FOLDER (new_folder),
                                                                 NULL,
                                                                 &error);
  /* failure expected */
  if (error != NULL)
    {
      g_warning ("Failed to copy map: add-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
    }

 out:
  g_clear_object (&copied_document);
  g_clear_object (&copied_folder);
  g_clear_object (&old_document);
  g_clear_object (&old_folder);
  g_clear_object (&new_document);
  g_clear_object (&ostream);
  g_clear_object (&new_folder);
  g_clear_object (&folder);
  g_clear_object (&parent);
  g_clear_object (&istream);
  g_clear_object (&local_file);
  g_clear_object (&service);
  g_clear_object (&client);
  g_list_free_full (accounts, g_object_unref);
  return 0;
}
