#include "bognor-connection-manager.h"

enum {
    PROP_0,
};

enum {
    LAST_SIGNAL,
};

struct _BognorConnectionManagerPrivate {
    int third;
};

#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), BOGNOR_TYPE_CONNECTION_MANAGER, BognorConnectionManagerPrivate))
G_DEFINE_TYPE (BognorConnectionManager, bognor_connection_manager, GUPNP_TYPE_SERVICE);
static guint32 signals[LAST_SIGNAL] = {0,};

/* FIXME: This should be generated by scanning GStreamer or the other one */
#if 0 /* We don't handle video yet...*/
static const char *sink_protocol_info = "http-get:*:audio/mpeg:*,http-get:*:application/ogg:*,http-get:*:audio/x-vorbis:*,http-get:*:audio/x-vorbis+ogg:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/x-ms-asf:*,http-get:*:audio/x-flac:*,http-get:*:audio/x-mod:*,http-get:*:audio/x-wav:*,http-get:*:audio/x-ac3:*,http-get:*:audio/x-m4a:*,http-get:*:video/x-theora:*,http-get:*:video/x-dirac:*,http-get:*:video/x-wmv:*,http-get:*:video/x-wma:*,http-get:*:video/x-msvideo:*,http-get:*:video/x-3ivx:*,http-get:*:video/x-3ivx:*,http-get:*:video/x-matroska:*,http-get:*:video/mpeg:*,http-get:*:video/x-ms-asf:*,http-get:*:video/x-xvid:*,http-get:*:video/x-ms-wmv:*";
#else
static const char *sink_protocol_info = "http-get:*:audio/mpeg:*,http-get:*:application/ogg:*,http-get:*:audio/x-vorbis:*,http-get:*:audio/x-vorbis+ogg:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/x-ms-asf:*,http-get:*:audio/x-flac:*,http-get:*:audio/x-mod:*,http-get:*:audio/x-wav:*,http-get:*:audio/x-ac3:*,http-get:*:audio/x-m4a:*";
#endif

static void
bognor_connection_manager_finalize (GObject *object)
{
    BognorConnectionManager *self = (BognorConnectionManager *) object;

    G_OBJECT_CLASS (bognor_connection_manager_parent_class)->finalize (object);
}

static void
bognor_connection_manager_dispose (GObject *object)
{
    BognorConnectionManager *self = (BognorConnectionManager *) object;

    G_OBJECT_CLASS (bognor_connection_manager_parent_class)->dispose (object);
}

static void
bognor_connection_manager_set_property (GObject      *object,
                          guint         prop_id,
                          const GValue *value,
                          GParamSpec   *pspec)
{
    BognorConnectionManager *self = (BognorConnectionManager *) object;

    switch (prop_id) {

    default:
        break;
    }
}

static void
bognor_connection_manager_get_property (GObject    *object,
                          guint       prop_id,
                          GValue     *value,
                          GParamSpec *pspec)
{
    BognorConnectionManager *self = (BognorConnectionManager *) object;

    switch (prop_id) {

    default:
        break;
    }
}

static void
bognor_connection_manager_class_init (BognorConnectionManagerClass *klass)
{
    GObjectClass *o_class = (GObjectClass *) klass;
    GUPnPServiceClass *s_class = (GUPnPServiceClass *) klass;

    o_class->dispose = bognor_connection_manager_dispose;
    o_class->finalize = bognor_connection_manager_finalize;
    o_class->set_property = bognor_connection_manager_set_property;
    o_class->get_property = bognor_connection_manager_get_property;

    g_type_class_add_private (klass, sizeof (BognorConnectionManagerPrivate));
}

static void
get_protocol_info_cb (GUPnPService            *service,
                      GUPnPServiceAction      *action,
                      BognorConnectionManager *manager)
{
    gupnp_service_action_set (action,
                              "Source", G_TYPE_STRING, "",
                              "Sink", G_TYPE_STRING, sink_protocol_info,
                              NULL);
    gupnp_service_action_return (action);
}

static void
get_current_connection_ids_cb (GUPnPService            *service,
                               GUPnPServiceAction      *action,
                               BognorConnectionManager *manager)
{
    gupnp_service_action_set (action,
                              "ConnectionIDs", G_TYPE_STRING, "0",
                              NULL);
    gupnp_service_action_return (action);
}

static void
get_current_connection_info_cb (GUPnPService            *service,
                                GUPnPServiceAction      *action,
                                BognorConnectionManager *manager)
{
    int connection_id;

    gupnp_service_action_get (action,
                              "ConnectionID", G_TYPE_INT, &connection_id,
                              NULL);

    if (connection_id != 0) {
        gupnp_service_action_return_error (action, 706, "Invalid connection reference");
        return;
    }

    gupnp_service_action_set (action,
                              "RcsID", G_TYPE_INT, 0,
                              "AVTransportID", G_TYPE_INT, 0,
                              "ProtocolInfo", G_TYPE_STRING, "",
                              "PeerConnectionManager", G_TYPE_STRING, "",
                              "PeerConnectionID", G_TYPE_INT, -1,
                              "Direction", G_TYPE_STRING, "Input",
                              "Status", G_TYPE_STRING, "Unknown",
                              NULL);
    gupnp_service_action_return (action);
}

static void
query_variable_cb (GUPnPService            *service,
                   char                    *variable,
                   GValue                  *value,
                   BognorConnectionManager *manager)
{
    g_print ("[Connection Manager] Query %s\n", variable);
    if (g_str_equal (variable, "CurrentConnectionIDs")) {
        g_value_init (value, G_TYPE_STRING);
        g_value_set_string (value, "0");
    } else if (g_str_equal (variable, "SinkProtocolInfo")) {
        g_value_init (value, G_TYPE_STRING);
        g_value_set_string (value, sink_protocol_info);
    } else if (g_str_equal (variable, "SourceProtocolInfo")) {
        g_value_init (value, G_TYPE_STRING);
        g_value_set_string (value, "");
    }
}

static void
bognor_connection_manager_init (BognorConnectionManager *self)
{
    BognorConnectionManagerPrivate *priv = GET_PRIVATE (self);

    self->priv = priv;

    g_signal_connect (self, "action-invoked::GetProtocolInfo",
                      G_CALLBACK (get_protocol_info_cb), self);
    g_signal_connect (self, "action-invoked::GetCurrentConnectionIDs",
                      G_CALLBACK (get_current_connection_ids_cb), self);
    g_signal_connect (self, "action-invoked::GetCurrentConnectionInfo",
                      G_CALLBACK (get_current_connection_info_cb), self);
    g_signal_connect (self, "query-variable",
                      G_CALLBACK (query_variable_cb), self);
}

