// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SHILL_GLIB_H_
#define SHILL_GLIB_H_

#include <string>

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

#include <base/macros.h>

namespace shill {

// A GLib abstraction allowing GLib mocking in tests.
class GLib {
 public:
  GLib();
  virtual ~GLib();

  // Converts GLib's |error| to a string message and frees the GError object.
  virtual std::string ConvertErrorToMessage(GError* error);

  // Thin wrappers around Base64Decode/Encode.  Return true on success.
  virtual bool B64Decode(const std::string& input, std::string* output);
  virtual bool B64Encode(const std::string& input, std::string* output);

  // g_child_watch_add
  virtual guint ChildWatchAdd(GPid pid,
                              GChildWatchFunc function,
                              gpointer data);
  // g_free
  virtual void Free(gpointer mem);
  // g_key_file_free
  virtual void KeyFileFree(GKeyFile* key_file);
  // g_key_file_get_boolean
  virtual gboolean KeyFileGetBoolean(GKeyFile* key_file,
                                     const gchar* group_name,
                                     const gchar* key,
                                     GError** error);
  // g_key_file_get_groups
  virtual gchar** KeyFileGetGroups(GKeyFile* key_file,
                                   gsize* length);
  // g_key_file_get_integer
  virtual gint KeyFileGetInteger(GKeyFile* key_file,
                                 const gchar* group_name,
                                 const gchar* key,
                                 GError** error);
  // g_key_file_get_string
  virtual gchar* KeyFileGetString(GKeyFile* key_file,
                                  const gchar* group_name,
                                  const gchar* key,
                                  GError** error);
  // g_key_file_get_string_list
  virtual gchar** KeyFileGetStringList(GKeyFile* key_file,
                                       const gchar* group_name,
                                       const gchar* key,
                                       gsize* length,
                                       GError** error);
  // g_key_file_has_group
  virtual gboolean KeyFileHasGroup(GKeyFile* key_file,
                                   const gchar* group_name);
  // g_key_file_has_key
  virtual gboolean KeyFileHasKey(GKeyFile* key_file,
                                 const gchar* group_name,
                                 const gchar* key,
                                 GError** error);
  // g_key_file_load_from_file
  virtual gboolean KeyFileLoadFromFile(GKeyFile* key_file,
                                       const gchar* file,
                                       GKeyFileFlags flags,
                                       GError** error);
  // g_key_file_new
  virtual GKeyFile* KeyFileNew();
  // g_key_file_remove_group
  virtual void KeyFileRemoveGroup(GKeyFile* key_file,
                                  const gchar* group_name,
                                  GError** error);
  // g_key_file_remove_key
  virtual void KeyFileRemoveKey(GKeyFile* key_file,
                                const gchar* group_name,
                                const gchar* key,
                                GError** error);
  // g_key_file_set_boolean
  virtual void KeyFileSetBoolean(GKeyFile* key_file,
                                 const gchar* group_name,
                                 const gchar* key,
                                 gboolean value);
  // g_key_file_set_comment
  virtual gboolean KeyFileSetComment(GKeyFile* key_file,
                                     const gchar* group_name,
                                     const gchar* key,
                                     const gchar* comment,
                                     GError** error);
  // g_key_file_set_integer
  virtual void KeyFileSetInteger(GKeyFile* key_file,
                                 const gchar* group_name,
                                 const gchar* key,
                                 gint value);
  // g_key_file_set_string
  virtual void KeyFileSetString(GKeyFile* key_file,
                                const gchar* group_name,
                                const gchar* key,
                                const gchar* value);
  // g_key_file_set_string_list
  virtual void KeyFileSetStringList(GKeyFile* key_file,
                                    const gchar* group_name,
                                    const gchar* key,
                                    const gchar* const list[],
                                    gsize length);
  // g_key_file_to_data
  virtual gchar* KeyFileToData(GKeyFile* key_file,
                               gsize* length,
                               GError** error);
  // g_source_remove
  virtual gboolean SourceRemove(guint tag);
  // g_spawn_async
  virtual gboolean SpawnAsync(const gchar* working_directory,
                              gchar** argv,
                              gchar** envp,
                              GSpawnFlags flags,
                              GSpawnChildSetupFunc child_setup,
                              gpointer user_data,
                              GPid* child_pid,
                              GError** error);
  // g_spawn_close_pid
  virtual void SpawnClosePID(GPid pid);
  // g_spawn_sync
  virtual gboolean SpawnSync(const gchar* working_directory,
                             gchar** argv,
                             gchar** envp,
                             GSpawnFlags flags,
                             GSpawnChildSetupFunc child_setup,
                             gpointer user_data,
                             gchar** standard_output,
                             gchar** standard_error,
                             gint* exit_status,
                             GError** error);
  // g_strfreev
  virtual void Strfreev(gchar** str_array);
  // g_type_init
  virtual void TypeInit();

 private:
  DISALLOW_COPY_AND_ASSIGN(GLib);
};

}  // namespace shill

#endif  // SHILL_GLIB_H_
