/* gcc $(pkg-config --cflags --libs libgdata goa-1.0 gio-2.0 glib-2.0)
   gdata-access-rule.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)
{
  GDataFeed *feed = NULL;
  GDataLink *link;
  GError *error = NULL;
  GList *authors;
  GList *entries;
  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_ACCESS_CONTROL_LIST);
  uri = gdata_link_get_uri (link);
  g_message ("access control list: %s", uri);

  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);
    }

  feed = gdata_access_handler_get_rules (GDATA_ACCESS_HANDLER (entry),
                                         GDATA_SERVICE (service),
                                         NULL,
                                         NULL, NULL, &error);
  if (error != NULL)
    {
      g_warning ("get-rules: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  entries = gdata_feed_get_entries (feed);
  for (k = entries; k != NULL; k = k->next)
    {
      GDataAccessRule *rule = GDATA_ACCESS_RULE (k->data);
      const gchar *key;
      const gchar *role;
      const gchar *scope_type;
      const gchar *scope_value;
      gint64 edited;

      key = gdata_access_rule_get_key (rule);
      g_message ("key: %s", key);

      role = gdata_access_rule_get_role (rule);
      g_message ("role: %s", role);

      gdata_access_rule_get_scope (rule, &scope_type, &scope_value);
      g_message ("scope_type: %s, scope_value: %s", scope_type, scope_value);

      edited = gdata_access_rule_get_edited (rule);
      g_message ("edited: %" G_GINT64_FORMAT, edited);
    }

 out:
  g_clear_object (&feed);
  g_list_free (links);
}

gint
main (void)
{
  GDataAccessRule *new_rule = NULL;
  GDataAuthorizationDomain *domain;
  GDataDocumentsAccessRule *rule = NULL;
  GDataDocumentsService *service = NULL;
  GDataEntry *entry = NULL;
  GDataLink *link;
  GError *error = 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;
    }

  id = "1JyRVk4gs3sfB53ZhUMICnmLFs1RRC5ADX7syVVBL70g";
  domain = gdata_documents_service_get_primary_authorization_domain ();

  error = NULL;
  entry = gdata_service_query_single_entry (GDATA_SERVICE (service),
                                            domain,
                                            id,
                                            NULL,
                                            GDATA_TYPE_DOCUMENTS_PRESENTATION,
                                            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, entry);

  link = gdata_entry_look_up_link (entry, GDATA_LINK_ACCESS_CONTROL_LIST);
  uri = gdata_link_get_uri (link);

  rule = gdata_documents_access_rule_new (NULL);
  gdata_access_rule_set_role (GDATA_ACCESS_RULE (rule), GDATA_DOCUMENTS_ACCESS_ROLE_READER);
  gdata_access_rule_set_scope (GDATA_ACCESS_RULE (rule), GDATA_ACCESS_SCOPE_USER, "matthias.clasen@gmail.com");

  error = NULL;
  new_rule = GDATA_ACCESS_RULE (gdata_service_insert_entry (GDATA_SERVICE (service),
                                                            domain,
                                                            uri,
                                                            GDATA_ENTRY (rule),
                                                            NULL,
                                                            &error));
  if (error != NULL)
    {
      g_warning ("insert-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  g_clear_object (&rule);
  g_clear_object (&new_rule);

  rule = gdata_documents_access_rule_new (NULL);
  gdata_access_rule_set_role (GDATA_ACCESS_RULE (rule), GDATA_DOCUMENTS_ACCESS_ROLE_WRITER);
  gdata_access_rule_set_scope (GDATA_ACCESS_RULE (rule), GDATA_ACCESS_SCOPE_USER, "jimmac@gmail.com");

  error = NULL;
  new_rule = GDATA_ACCESS_RULE (gdata_service_insert_entry (GDATA_SERVICE (service),
                                                            domain,
                                                            uri,
                                                            GDATA_ENTRY (rule),
                                                            NULL,
                                                            &error));
  if (error != NULL)
    {
      g_warning ("insert-entry: (%s): %s", g_quark_to_string (error->domain), error->message);
      g_error_free (error);
      goto out;
    }

  g_clear_object (&entry);

  error = NULL;
  entry = gdata_service_query_single_entry (GDATA_SERVICE (service),
                                            domain,
                                            id,
                                            NULL,
                                            GDATA_TYPE_DOCUMENTS_PRESENTATION,
                                            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, entry);

 out:
  g_clear_object (&new_rule);
  g_clear_object (&rule);
  g_clear_object (&entry);
  g_clear_object (&service);
  g_clear_object (&client);
  g_list_free_full (accounts, g_object_unref);
  return 0;
}
