flatpak_dir_remove_remote (FlatpakDir   *self,
                           gboolean      force_remove,
                           const char   *remote_name,
                           GCancellable *cancellable,
                           GError      **error)
{
  g_autofree char *prefix = NULL;
  g_autoptr(GHashTable) refs = NULL;
  GHashTableIter hash_iter;
  gpointer key;
  g_autofree char *url = NULL;

  if (flatpak_dir_use_system_helper (self, NULL))
    {
      g_autoptr(GVariant) gpg_data_v = NULL;
      FlatpakHelperConfigureRemoteFlags flags = 0;
      const char *installation = flatpak_dir_get_id (self);

      gpg_data_v = g_variant_ref_sink (g_variant_new_from_data (G_VARIANT_TYPE ("ay"), "", 0, TRUE, NULL, NULL));

      if (force_remove)
        flags |= FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_FORCE_REMOVE;

      if (!flatpak_dir_system_helper_call_configure_remote (self,
                                                            flags, remote_name,
                                                            "",
                                                            gpg_data_v,
                                                            installation ? installation : "",
                                                            cancellable, error))
        return FALSE;

      return TRUE;
    }

  if (!flatpak_dir_ensure_repo (self, cancellable, error))
    return FALSE;

  if (!ostree_repo_list_refs (self->repo,
                              NULL,
                              &refs,
                              cancellable, error))
    return FALSE;

  prefix = g_strdup_printf ("%s:", remote_name);

  if (!force_remove)
    {
      g_hash_table_iter_init (&hash_iter, refs);
      while (g_hash_table_iter_next (&hash_iter, &key, NULL))
        {
          const char *refspec = key;

          if (!g_str_has_prefix (refspec, prefix))
            continue;

          g_autoptr(FlatpakDecomposed) ref = flatpak_decomposed_new_from_refspec (refspec, NULL);
          if (ref == NULL)
            continue;

          g_autofree char *origin = flatpak_dir_get_origin (self, ref, cancellable, NULL);
          if (g_strcmp0 (origin, remote_name) == 0)
            return flatpak_fail_error (error, FLATPAK_ERROR_REMOTE_USED,
                                       _("Can't remove remote '%s' with installed ref %s (at least)"),
                                       remote_name, flatpak_decomposed_get_ref (ref));
        }
    }

  /* Remove all refs */
  g_hash_table_iter_init (&hash_iter, refs);
  while (g_hash_table_iter_next (&hash_iter, &key, NULL))
    {
      const char *refspec = key;

      if (g_str_has_prefix (refspec, prefix) &&
          !flatpak_dir_remove_ref (self, remote_name, refspec + strlen (prefix), cancellable, error))
        return FALSE;
    }

  if (!flatpak_dir_remove_appstream (self, remote_name,
                                     cancellable, error))
    return FALSE;

  if (flatpak_dir_get_remote_oci (self, remote_name) &&
      !flatpak_dir_remove_oci_files (self, remote_name,
                                     cancellable, error))
    return FALSE;

  ostree_repo_remote_get_url (self->repo, remote_name, &url, NULL);

  if (!ostree_repo_remote_change (self->repo, NULL,
                                  OSTREE_REPO_REMOTE_CHANGE_DELETE,
                                  remote_name, NULL,
                                  NULL,
                                  cancellable, error))
    return FALSE;

  if (!flatpak_dir_mark_changed (self, error))
    return FALSE;

  flatpak_dir_log (self, "remove remote",
                   remote_name, NULL, NULL, NULL, url,
                   "Removed remote %s", remote_name);

  return TRUE;
}