#include "pipewire.h"
#include <stdexcept>
#include <QDebug>

static const struct pw_registry_events registry_events = {
	.version = PW_VERSION_REGISTRY_EVENTS,
	.global = &PipeWireHandler::registryEventHandler,
	.global_remove = nullptr
};

PipeWireHandler::PipeWireHandler()
{
	loop = pw_thread_loop_new("SHinterface", nullptr);
	if(!loop)
		throw std::runtime_error("Could not create pipewire main loop");

	context = pw_context_new(pw_thread_loop_get_loop(loop), nullptr, 0);
	if(!context)
		throw std::runtime_error("Could not create pipewire context");

	core = pw_context_connect(context, NULL, 0);
	if(!core)
		throw std::runtime_error("Could not connect to pipewire");

	registry = pw_core_get_registry(core, PW_VERSION_REGISTRY, 0);
	if(!registry)
		throw std::runtime_error("Could not get pipewire registry");

	spa_zero(registryListener);
	pw_registry_add_listener(registry, &registryListener, &registry_events, this);
}

bool PipeWireHandler::startLoop()
{
	if(!loop || !context || !core || !registry)
		return false;
	int ret = pw_thread_loop_start(loop);
	return ret == 0;
}

struct pw_registry* PipeWireHandler::getRegistry()
{
	return registry;
}

void PipeWireHandler::registryEventHandler(void *data, uint32_t id,
                                           uint32_t permissions, const char *type, uint32_t version,
                                           const struct spa_dict *props)
{
	(void)permissions;
	(void)version;

	PipeWireHandler* handler = static_cast<PipeWireHandler*>(data);

	if(std::string(type) == PW_TYPE_INTERFACE_Node)
	{
		const struct spa_dict_item *item = spa_dict_lookup_item(props, "node.name");
		if(item)
		{
			qDebug()<<"got new pipewire node:"<<id<<"name:"<<item->value;
			handler->nodeAdded({id, item->value});
		}
	}
}

PipeWireHandler::~PipeWireHandler()
{
	pw_core_disconnect(core);
	pw_context_destroy(context);
	pw_thread_loop_stop(loop);
}

