#include "service_model.h"
#include <glib.h>

struct _Service {
    GObject parent_instance;
    gchar *name;
    gchar *state;
    gchar *active;
    gchar *sub;
    gchar *description;
};

struct _ServiceClass {
    GObjectClass parent_class;
};

G_DEFINE_TYPE(Service, service, G_TYPE_OBJECT)

enum {
    PROP_0,
    PROP_NAME,
    PROP_STATE,
    PROP_ACTIVE,
    PROP_SUB,
    PROP_DESCRIPTION,
    N_PROPERTIES
};

static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };

static void service_dispose(GObject *gobject)
{
    Service *self = (Service *)gobject;
    g_clear_pointer(&self->name, g_free);
    g_clear_pointer(&self->state, g_free);
    g_clear_pointer(&self->active, g_free);
    g_clear_pointer(&self->sub, g_free);
    g_clear_pointer(&self->description, g_free);
    G_OBJECT_CLASS(service_parent_class)->dispose(gobject);
}

static void service_get_property(GObject *object, guint prop_id,
                                 GValue *value, GParamSpec *pspec)
{
    Service *self = (Service *)object;
    switch (prop_id) {
    case PROP_NAME:
        g_value_set_string(value, self->name);
        break;
    case PROP_STATE:
        g_value_set_string(value, self->state);
        break;
    case PROP_ACTIVE:
        g_value_set_string(value, self->active);
        break;
    case PROP_SUB:
        g_value_set_string(value, self->sub);
        break;
    case PROP_DESCRIPTION:
        g_value_set_string(value, self->description);
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    }
}

static void service_set_property(GObject *object, guint prop_id,
                                 const GValue *value, GParamSpec *pspec)
{
    Service *self = (Service *)object;
    switch (prop_id) {
    case PROP_NAME:
        g_free(self->name);
        self->name = g_value_dup_string(value);
        break;
    case PROP_STATE:
        g_free(self->state);
        self->state = g_value_dup_string(value);
        break;
    case PROP_ACTIVE:
        g_free(self->active);
        self->active = g_value_dup_string(value);
        break;
    case PROP_SUB:
        g_free(self->sub);
        self->sub = g_value_dup_string(value);
        break;
    case PROP_DESCRIPTION:
        g_free(self->description);
        self->description = g_value_dup_string(value);
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    }
}

static void service_class_init(ServiceClass *klass)
{
    GObjectClass *object_class = G_OBJECT_CLASS(klass);
    object_class->dispose = service_dispose;
    object_class->get_property = service_get_property;
    object_class->set_property = service_set_property;

    obj_properties[PROP_NAME] =
        g_param_spec_string("name", "Name", "Service name", NULL,
                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT);

    obj_properties[PROP_STATE] =
        g_param_spec_string("state", "State", "Service state", NULL,
                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT);

    obj_properties[PROP_ACTIVE] =
        g_param_spec_string("active", "Active", "Active state", NULL,
                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT);

    obj_properties[PROP_SUB] =
        g_param_spec_string("sub", "Sub", "Sub state", NULL,
                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT);

    obj_properties[PROP_DESCRIPTION] =
        g_param_spec_string("description", "Description", "Service description", NULL,
                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT);

    /* Install properties array (obj_properties[0] is unused and must be NULL) */
    g_object_class_install_properties(object_class, N_PROPERTIES, obj_properties);
}

static void service_init(Service *self)
{
    /* nothing */
}

Service *service_new(const gchar *name, const gchar *state, const gchar *active, const gchar *sub, const gchar *description)
{
    return g_object_new(SERVICE_TYPE,
                        "name", name,
                        "state", state,
                        "active", active,
                        "sub", sub,
                        "description", description,
                        NULL);
}
