/*
 * valac --pkg gio-2.0 ./test_signal.vala
 */

using GLib;

[DBus (name = "com.example.interface")]
public class ItemView : Object {
  public struct added_contacts_t {
    public string id;
    [DBus (signature = "a{sas}")]
    public Variant attrs;
  }
  [DBus (signature = "a(sa{sas})")]
  public signal void ContactsAdded (added_contacts_t[] contacts);
}

public void on_bus_aquired (DBusConnection conn)
{
}

public int main ()
{
  var conn = Bus.get_sync (BusType.SESSION);
  var view = new ItemView ();
  conn.register_object ("/path", view);

  var contacts = new ItemView.added_contacts_t[1];
  contacts[0].id = "id";
  contacts[0].attrs = new Variant.parsed ("{'field1': ['value1'], 'field2': ['value2']}");
  message ("attrs type = %s", contacts[0].attrs.get_type_string ());

  Variant v = new Variant.parsed (
    "([('id', {'field1': ['value1'], 'field2': ['value2']}), "
    + "('id2', {'f1': ['value1'], 'f2': ['value2']})],)");
  message ("variant type = %s", v.get_type_string ());

  Bus.own_name (
    BusType.SESSION, "com.example.testsignal",
    BusNameOwnerFlags.NONE,
    on_bus_aquired,
    () =>
      {
        /* This one works */
        conn.emit_signal (null, "/path",
            "com.example.interface", "ContactsAdded",
            v);
        /* This one gives a critical error */
        view.ContactsAdded (contacts);
      },
    () =>
      {
        message ("Could not aquire D-Bus name\n");
        assert_not_reached ();
      });

  var main_loop = new GLib.MainLoop (null, false);
  uint timer_id = Timeout.add_seconds (2, () =>
    {
      main_loop.quit ();
      return false;
    });
  main_loop.run ();

  return 0;
}
