/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2010 Apple Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <CoreFoundation/CoreFoundation.h>
#include <dns_sd.h>
#include <UserEventAgentInterface.h>
#include <stdio.h>
#include <stdlib.h>


#pragma mark -
#pragma mark Types
#pragma mark -
static const char*			sPluginIdentifier		= "com.apple.bonjour.events";

// PLIST Keys
static const CFStringRef	sServiceNameKey			= CFSTR("ServiceName");
static const CFStringRef	sServiceTypeKey			= CFSTR("ServiceType");
static const CFStringRef	sServiceDomainKey		= CFSTR("ServiceDomain");

static const CFStringRef	sOnServiceAddKey		= CFSTR("OnServiceAdd");
static const CFStringRef	sOnServiceRemoveKey		= CFSTR("OnServiceRemove");
static const CFStringRef    sWhileServiceExistsKey	= CFSTR("WhileServiceExists");

static const CFStringRef	sLaunchdTokenKey		= CFSTR("LaunchdToken");

static const CFStringRef	sPluginTimersKey		= CFSTR("PluginTimers");


/************************************************
 * Launch Event Dictionary (input from launchd)
 * Passed To: ManageEventsCallback
 *-----------------------------------------------
 * Typing in this dictionary is not enforced 
 * above us. So this may not be true. Type check
 * all input before using it.
 *-----------------------------------------------
 * sServiceNameKey		- CFString (Optional) 
 * sServiceTypeKey		- CFString
 * sServiceDomainKey	- CFString
 *
 * One or more of the following.
 *-----------------------------------
 * sOnServiceAddKey			- CFBoolean
 * sOnServiceRemoveKey		- CFBoolean 
 * sWhileServiceExistsKey	- CFBoolean
 ************************************************/

/************************************************
 * Browser Dictionary
 *-----------------------------------------------
 * sServiceDomainKey - CFString
 * sServiceTypeKey   - CFString
 ************************************************/

/************************************************
 * Event Dictionary
 *-----------------------------------------------
 * sServiceNameKey	 - CFString (Optional) 
 * sLaunchdTokenKey	 - CFNumber
 ************************************************/

typedef struct {
    UserEventAgentInterfaceStruct*		_UserEventAgentInterface;
    CFUUIDRef							_factoryID;
    UInt32								_refCount;
	
	void*								_pluginContext;
	
	CFMutableDictionaryRef				_tokenToBrowserMap;		// Maps a token to a browser that can be used to scan the remaining dictionaries.
	CFMutableDictionaryRef				_browsers;				// A Dictionary of "Browser Dictionarys" where the resposible browser is the key.
	CFMutableDictionaryRef				_onAddEvents;			// A Dictionary of "Event Dictionarys" that describe events to trigger on a service appearing.
	CFMutableDictionaryRef				_onRemoveEvents;		// A Dictionary of "Event Dictionarys" that describe events to trigger on a service disappearing.
	CFMutableDictionaryRef				_whileServiceExist;		// A Dictionary of "Event Dictionarys" that describe events to trigger on a service disappearing.

	
	CFMutableArrayRef					_timers;

} BonjourUserEventsPlugin;


typedef struct {
	
	CFIndex	 refCount;
	BonjourUserEventsPlugin* plugin;
	CFNumberRef token;
	
} TimerContextInfo;

typedef struct {
	CFIndex refCount;
	DNSServiceRef browserRef;
} NetBrowserInfo;

#pragma mark -
#pragma mark Prototypes
#pragma mark -
// COM Stuff
static HRESULT	QueryInterface(void *myInstance, REFIID iid, LPVOID *ppv);
static ULONG	AddRef(void* instance);
static ULONG	Release(void* instance);

static BonjourUserEventsPlugin* Alloc(CFUUIDRef factoryID);
static void Dealloc(BonjourUserEventsPlugin* plugin);

void * UserEventAgentFactory(CFAllocatorRef allocator, CFUUIDRef typeID);

// Plugin Management
static void Install(void* instance);
static void ManageEventsCallback(
						  UserEventAgentLaunchdAction action,
						  CFNumberRef                 token,
						  CFTypeRef                   eventMatchDict,
						  void                      * vContext);


// Plugin Guts
void AddEventToPlugin(BonjourUserEventsPlugin* plugin, CFNumberRef launchdToken, CFDictionaryRef eventParameters);
void RemoveEventFromPlugin(BonjourUserEventsPlugin* plugin, CFNumberRef	launchToken);

NetBrowserInfo* CreateBrowserForTypeAndDomain(BonjourUserEventsPlugin* plugin, CFStringRef type, CFStringRef domain);
NetBrowserInfo* BrowserForSDRef(BonjourUserEventsPlugin* plugin, DNSServiceRef sdRef);
void AddEventDictionary(CFDictionaryRef eventDict, CFMutableDictionaryRef allEventsDictionary, NetBrowserInfo* key);
void RemoveEventFromArray(CFMutableArrayRef array, CFNumberRef launchdToken);

// Net Service Browser Stuff
void ServiceBrowserCallback (DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char* serviceName, const char* regtype, const char* replyDomain, void* context);
void HandleTemporaryEventsForService(BonjourUserEventsPlugin* plugin, NetBrowserInfo* browser, CFStringRef serviceName, CFMutableDictionaryRef eventsDictionary);
void HandleStateEventsForService(BonjourUserEventsPlugin* plugin, NetBrowserInfo* browser,  CFStringRef serviceName, Boolean didAppear);
void TemporaryEventTimerCallout ( CFRunLoopTimerRef timer, void *info );

// Convence Stuff
const char* CStringFromCFString(CFStringRef string);


// TimerContextInfo "Object"
TimerContextInfo* TimerContextInfoCreate(BonjourUserEventsPlugin* plugin, CFNumberRef token);
const void* TimerContextInfoRetain(const void* info);
void TimerContextInfoRelease(const void* info);
CFStringRef TimerContextInfoCopyDescription(const void* info);

// NetBrowserInfo "Object"
NetBrowserInfo* NetBrowserInfoCreate(CFStringRef serviceType, CFStringRef domain, void* context);
const void* NetBrowserInfoRetain(CFAllocatorRef allocator, const void* info);
void NetBrowserInfoRelease(CFAllocatorRef allocator, const void* info);
Boolean	NetBrowserInfoEqual(const void *value1, const void *value2);
CFHashCode	NetBrowserInfoHash(const void *value);
CFStringRef	NetBrowserInfoCopyDescription(const void *value);


static const CFDictionaryKeyCallBacks kNetBrowserInfoDictionaryKeyCallbacks = { 
	0, 
	NetBrowserInfoRetain, 
	NetBrowserInfoRelease,
	NetBrowserInfoCopyDescription,
	NetBrowserInfoEqual,
	NetBrowserInfoHash
};

static const CFDictionaryValueCallBacks kNetBrowserInfoDictionaryValueCallbacks = { 
	0, 
	NetBrowserInfoRetain, 
	NetBrowserInfoRelease,
	NetBrowserInfoCopyDescription,
	NetBrowserInfoEqual	
};

// COM type definition goop.
static UserEventAgentInterfaceStruct UserEventAgentInterfaceFtbl = {
	NULL,                   // Required padding for COM
	QueryInterface,			// Query Interface
	AddRef,					// AddRef()
	Release,				// Release()
	Install					// Install 
}; 

#pragma mark -
#pragma mark COM Management
#pragma mark -

/*****************************************************************************
 *****************************************************************************/
static HRESULT QueryInterface(void *myInstance, REFIID iid, LPVOID *ppv) 
{
	CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes(NULL, iid);
	
	// Test the requested ID against the valid interfaces.
	if(CFEqual(interfaceID, kUserEventAgentInterfaceID)) 
	{
		((BonjourUserEventsPlugin *) myInstance)->_UserEventAgentInterface->AddRef(myInstance);
		*ppv = myInstance;
		CFRelease(interfaceID);
		return S_OK;
	} 
	else if(CFEqual(interfaceID, IUnknownUUID)) 
	{
		((BonjourUserEventsPlugin *) myInstance)->_UserEventAgentInterface->AddRef(myInstance);
		*ppv = myInstance;
		CFRelease(interfaceID);
		return S_OK;
    } 
	else //  Requested interface unknown, bail with error.
	{ 
		*ppv = NULL;
		CFRelease(interfaceID);
		return E_NOINTERFACE;
	}
}

/*****************************************************************************
 *****************************************************************************/
static ULONG AddRef(void* instance)
{
	BonjourUserEventsPlugin* plugin = (BonjourUserEventsPlugin*)instance;
	return 	++plugin->_refCount;
}

/*****************************************************************************
 *****************************************************************************/
static ULONG Release(void* instance)
{
	BonjourUserEventsPlugin* plugin = (BonjourUserEventsPlugin*)instance;

	if (plugin->_refCount != 0)
		--plugin->_refCount;
	
	if (plugin->_refCount == 0)
	{
		Dealloc(instance);
		return 0;
	}
	
	return plugin->_refCount;
} 

/*****************************************************************************
 * Alloc
 * - 
 * Functionas as both +[alloc] and -[init] for the plugin. Add any 
 * initalization of member variables here.
 *****************************************************************************/
static BonjourUserEventsPlugin* Alloc(CFUUIDRef factoryID)
{
	BonjourUserEventsPlugin* plugin = malloc(sizeof(BonjourUserEventsPlugin));
	
	plugin->_UserEventAgentInterface = &UserEventAgentInterfaceFtbl;
	plugin->_pluginContext = NULL;
		
	if (factoryID) 
	{
		plugin->_factoryID = (CFUUIDRef)CFRetain(factoryID);
		CFPlugInAddInstanceForFactory(factoryID);
	}
	
	plugin->_refCount = 1;
	plugin->_tokenToBrowserMap = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kNetBrowserInfoDictionaryValueCallbacks);
	plugin->_browsers = CFDictionaryCreateMutable(NULL, 0, &kNetBrowserInfoDictionaryKeyCallbacks, &kCFTypeDictionaryValueCallBacks);
	plugin->_onAddEvents = CFDictionaryCreateMutable(NULL, 0, &kNetBrowserInfoDictionaryKeyCallbacks, &kCFTypeDictionaryValueCallBacks);
	plugin->_onRemoveEvents = CFDictionaryCreateMutable(NULL, 0, &kNetBrowserInfoDictionaryKeyCallbacks, &kCFTypeDictionaryValueCallBacks);
	plugin->_whileServiceExist = CFDictionaryCreateMutable(NULL, 0, &kNetBrowserInfoDictionaryKeyCallbacks, &kCFTypeDictionaryValueCallBacks);
	
	plugin->_timers = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
	
	return plugin;
}

/*****************************************************************************
 * Dealloc
 * - 
 * Much like Obj-C dealloc this method is responsible for releasing any object
 * this plugin is holding. Unlike ObjC, you call directly free() instead of 
 * [super dalloc].
 *****************************************************************************/
static void Dealloc(BonjourUserEventsPlugin* plugin)
{
	CFUUIDRef factoryID = plugin->_factoryID;
	
	if (factoryID)
	{
		CFPlugInRemoveInstanceForFactory(factoryID);
		CFRelease(factoryID);
	}
	
	if (plugin->_tokenToBrowserMap)
		CFRelease(plugin->_tokenToBrowserMap);
	
	if (plugin->_browsers)
		CFRelease(plugin->_browsers);
	
	if (plugin->_onAddEvents)
		CFRelease(plugin->_onAddEvents);
	
	if (plugin->_onRemoveEvents)
		CFRelease(plugin->_onRemoveEvents);
	
	if (plugin->_whileServiceExist)
		CFRelease(plugin->_whileServiceExist);
	
	if (plugin->_timers)
	{
		CFIndex i;
		CFIndex count = CFArrayGetCount(plugin->_timers);
		CFRunLoopRef crl = CFRunLoopGetCurrent();
		
		for (i = 0; i < count; ++i)
		{
			CFRunLoopTimerRef timer = (CFRunLoopTimerRef)CFArrayGetValueAtIndex(plugin->_timers, i);
			CFRunLoopRemoveTimer(crl, timer, kCFRunLoopCommonModes);
		}
		
		CFRelease(plugin->_timers);
	}
	
	free(plugin);
}

/*******************************************************************************
 *******************************************************************************/
void * UserEventAgentFactory(CFAllocatorRef allocator, CFUUIDRef typeID)
{
	(void)allocator;
    BonjourUserEventsPlugin * result = NULL;
	
    if (typeID && CFEqual(typeID, kUserEventAgentTypeID)) {
        result = Alloc(kUserEventAgentFactoryID);
    }
	
    return (void *)result;
}

#pragma mark -
#pragma mark Plugin Management
#pragma mark -
/*****************************************************************************
 * Install
 * -
 * This is invoked once when the plugin is loaded to do initial setup and
 * allow us to register with launchd. If UserEventAgent crashes, the plugin 
 * will need to be reloaded, and hence this will get invoked again.
 *****************************************************************************/
static void Install(void *instance)
{
	BonjourUserEventsPlugin* plugin = (BonjourUserEventsPlugin*)instance;
	
	plugin->_pluginContext = UserEventAgentRegisterForLaunchEvents(sPluginIdentifier, &ManageEventsCallback, plugin);
	
	if (!plugin->_pluginContext)
	{
		fprintf(stderr, "%s: failed to register for launch events.\n", sPluginIdentifier);
		return;
	}
	
}

/*****************************************************************************
 * ManageEventsCallback
 * - 
 * This is invoked when launchd loads a event dictionary and needs to inform 
 * us what a daemon / agent is looking for.
 *****************************************************************************/
static void ManageEventsCallback(UserEventAgentLaunchdAction action, CFNumberRef token, CFTypeRef eventMatchDict, void* vContext)
{
	
	if (!eventMatchDict || CFGetTypeID(eventMatchDict) != CFDictionaryGetTypeID())
	{
		fprintf(stderr, "%s given non-dictionary for event dictionary\n", sPluginIdentifier);
		return;
	}
	
	if (action == kUserEventAgentLaunchdAdd)
	{
		// Launchd wants us to add a launch event for this token and matching dictionary.
		AddEventToPlugin((BonjourUserEventsPlugin*)vContext, token, (CFDictionaryRef)eventMatchDict);
	}
	else if (action == kUserEventAgentLaunchdRemove)
	{
		// Launchd wants us to remove the event hook we setup for this token / matching dictionary.
		RemoveEventFromPlugin((BonjourUserEventsPlugin*)vContext, token);
	}
	else
	{
		fprintf(stderr, "%s got unknown UserEventAction: %d\n", sPluginIdentifier, action);
	}
}


#pragma mark -
#pragma mark Plugin Guts
#pragma mark -

/*****************************************************************************
 * AddEventToPlugin
 * - 
 * This method is invoked when launchd wishes the plugin to setup a launch 
 * event matching the parameters in the dictionary.
 *****************************************************************************/
void AddEventToPlugin(BonjourUserEventsPlugin* plugin, CFNumberRef launchdToken, CFDictionaryRef eventParameters)
{
	CFStringRef		domain = CFDictionaryGetValue(eventParameters, sServiceDomainKey);
	CFStringRef		type = CFDictionaryGetValue(eventParameters, sServiceTypeKey);
	CFStringRef		name = CFDictionaryGetValue(eventParameters, sServiceNameKey);
	CFBooleanRef	cfOnAdd = CFDictionaryGetValue(eventParameters, sOnServiceAddKey);
	CFBooleanRef	cfOnRemove = CFDictionaryGetValue(eventParameters, sOnServiceRemoveKey);
	CFBooleanRef    cfWhileSericeExists = CFDictionaryGetValue(eventParameters, sWhileServiceExistsKey);
	
	Boolean			onAdd = false;
	Boolean			onRemove = false;
	Boolean			whileExists = false;
	
	if (cfOnAdd && CFGetTypeID(cfOnRemove) == CFBooleanGetTypeID() && CFBooleanGetValue(cfOnAdd))
		onAdd = true;
	
	if (cfOnRemove && CFGetTypeID(cfOnRemove) == CFBooleanGetTypeID() && CFBooleanGetValue(cfOnRemove))
		onRemove = true;
	
	if (cfWhileSericeExists && CFGetTypeID(cfWhileSericeExists) == CFBooleanGetTypeID() && CFBooleanGetValue(cfWhileSericeExists))
		whileExists = true;
	
	// A type is required. If none is specified, BAIL
	if (!type || CFGetTypeID(type) != CFStringGetTypeID()) 
	{
		fprintf(stderr, "%s, a LaunchEvent is missing a service type.\n", sPluginIdentifier);
		return;
	}
	
	// If we aren't suppose to launch on services appearing or disappearing, this service does nothing. Ignore.
	if ((!onAdd && !onRemove && !whileExists) || (onAdd && onRemove && whileExists))
	{
		fprintf(stderr, "%s, a LaunchEvent is missing both onAdd/onRemove/existance or has both.\n", sPluginIdentifier);
		return;
	}

	// If no domain is specified, assume local.
	if (!domain)
	{
		domain = CFSTR("local"); 
	}
	else if (CFGetTypeID(domain) != CFStringGetTypeID() ) // If the domain is not a string, fai;
	{
		fprintf(stderr, "%s, a LaunchEvent has a domain that is not a string.\n", sPluginIdentifier);
		return;
	}

	
	// If we have a name filter, but it's not a string. This event it broken, bail.
	if (name && CFGetTypeID(name) != CFStringGetTypeID())
	{
		fprintf(stderr, "%s, a LaunchEvent has a domain that is not a string.\n", sPluginIdentifier);
		return;
	}
	
	// Get us a browser
	NetBrowserInfo* browser = CreateBrowserForTypeAndDomain(plugin, type, domain);
	
	if (!browser)
	{
		fprintf(stderr, "%s, a LaunchEvent has a domain that is not a string.\n", sPluginIdentifier);
		return;
	}
	
	// Create Event Dictionary
	CFMutableDictionaryRef eventDictionary = CFDictionaryCreateMutable(NULL, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	
	
	CFDictionarySetValue(eventDictionary, sLaunchdTokenKey, launchdToken);
	
	if (name)
		CFDictionarySetValue(eventDictionary, sServiceNameKey, name);
	
	// Add to the correct dictionary.
	if (onAdd)
		AddEventDictionary(eventDictionary, plugin->_onAddEvents, browser);
	
	if (onRemove)
		AddEventDictionary(eventDictionary, plugin->_onRemoveEvents, browser);
	
	if (whileExists)
		AddEventDictionary(eventDictionary, plugin->_whileServiceExist, browser);
	
	// Add Token Mapping
	CFDictionarySetValue(plugin->_tokenToBrowserMap, launchdToken, browser);
	
	// Release Memory
	CFRelease(eventDictionary);
	NetBrowserInfoRelease(NULL, browser);
	
}



/*****************************************************************************
 * RemoveEventFromPlugin
 * - 
 * This method is invoked when launchd wishes the plugin to setup a launch 
 * event matching the parameters in the dictionary.
 *****************************************************************************/
void RemoveEventFromPlugin(BonjourUserEventsPlugin* plugin, CFNumberRef	launchdToken)
{
	NetBrowserInfo* browser = (NetBrowserInfo*)CFDictionaryGetValue(plugin->_tokenToBrowserMap, launchdToken);
	Boolean othersUsingBrowser = false;
	
	if (!browser)
	{
		long long value = 0;
		CFNumberGetValue(launchdToken, kCFNumberLongLongType, &value);
		fprintf(stderr, "%s, Launchd asked us to remove a token we did not register!\nToken:%lld\n", sPluginIdentifier, value);
		return;
	}
	
	CFMutableArrayRef onAddEvents = (CFMutableArrayRef)CFDictionaryGetValue(plugin->_onAddEvents, browser);
	CFMutableArrayRef onRemoveEvents = (CFMutableArrayRef)CFDictionaryGetValue(plugin->_onRemoveEvents, browser);
	
	if (onAddEvents)
	{
		RemoveEventFromArray(onAddEvents, launchdToken);
				
		// Is the array now empty, clean up 
		if (CFArrayGetCount(onAddEvents) == 0)
			CFDictionaryRemoveValue(plugin->_onAddEvents, browser);
	}

	if (onRemoveEvents)
	{
		RemoveEventFromArray(onRemoveEvents, launchdToken);
		
		// Is the array now empty, clean up 
		if (CFArrayGetCount(onRemoveEvents) == 0)
			CFDictionaryRemoveValue(plugin->_onRemoveEvents, browser);
	}
	
	// Remove ourselves from the token dictionary.
	CFDictionaryRemoveValue(plugin->_tokenToBrowserMap, launchdToken);
	
	// Check to see if anyone else is using this browser.
	CFIndex i;
	CFIndex count = CFDictionaryGetCount(plugin->_tokenToBrowserMap);
	NetBrowserInfo** browsers = malloc(count * sizeof(NetBrowserInfo*));

	// Fetch the values of the token dictionary
	CFDictionaryGetKeysAndValues(plugin->_tokenToBrowserMap, NULL, (const void**)browsers);

	for (i = 0; i < count; ++i)
	{
		if (NetBrowserInfoEqual(browsers[i], browser))
		{
			othersUsingBrowser = true;
			break;
		}
	}
	
	// If no one else is useing our browser, clean up!
	if (!othersUsingBrowser)
	{
		CFDictionaryRemoveValue(plugin->_tokenToBrowserMap, launchdToken); // This triggers release and dealloc of the browser
	}
	
	free(browsers);
}


/*****************************************************************************
 * CreateBrowserForTypeAndDomain
 * - 
 * This method returns a NetBrowserInfo that is looking for a type of 
 * service in a domain. If no browser exists, it will create one and return it.
 *****************************************************************************/
NetBrowserInfo* CreateBrowserForTypeAndDomain(BonjourUserEventsPlugin* plugin, CFStringRef type, CFStringRef domain)
{
	CFIndex i;
	CFIndex count = CFDictionaryGetCount(plugin->_browsers);
	NetBrowserInfo* browser = NULL;
	CFDictionaryRef* dicts = malloc(count * sizeof(CFDictionaryRef));
	NetBrowserInfo** browsers = malloc(count * sizeof(NetBrowserInfo*));
	
	// Fetch the values of the browser dictionary
	CFDictionaryGetKeysAndValues(plugin->_browsers, (const void**)browsers, (const void**)dicts);
	
	// Loop thru the browsers list and see if we can find a matching one.
	for (i = 0; i < count; ++i)
	{
		CFDictionaryRef browserDict = dicts[i];

		CFStringRef browserType = CFDictionaryGetValue(browserDict, sServiceTypeKey);
		CFStringRef browserDomain = CFDictionaryGetValue(browserDict, sServiceDomainKey);
		
		// If we have a matching browser, break
		if (CFStringCompare(browserType, type, kCFCompareCaseInsensitive) &&
			CFStringCompare(browserDomain, domain, kCFCompareCaseInsensitive))
		{
			browser = browsers[i];
			NetBrowserInfoRetain(NULL, browser);
			break;
		}
	}
	
	// No match found, lets create one!
	if (!browser)
	{
		
		browser = NetBrowserInfoCreate(type, domain, plugin);
		
		if (!browser)
		{			
			fprintf(stderr, "%s, failed to search for %s.%s", sPluginIdentifier, CStringFromCFString(type) , CStringFromCFString(domain));
			free(dicts);
			free(browsers);
			return NULL;
		}
		
		// Service browser created, lets add this to ourselves to the dictionary.
		CFMutableDictionaryRef browserDict = CFDictionaryCreateMutable(NULL, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
		
		CFDictionarySetValue(browserDict, sServiceTypeKey, type);
		CFDictionarySetValue(browserDict, sServiceDomainKey, domain);
		
		// Add the dictionary to the browsers dictionary.
		CFDictionarySetValue(plugin->_browsers, browser, browserDict);
		
		// Release Memory
		CFRelease(browserDict);
	}
	
	free(dicts);
	free(browsers);
	
	return browser;
}

/*****************************************************************************
 * BrowserForSDRef
 * - 
 * This method returns a NetBrowserInfo that matches the calling SDRef passed
 * in via the callback.
 *****************************************************************************/
NetBrowserInfo* BrowserForSDRef(BonjourUserEventsPlugin* plugin, DNSServiceRef sdRef)
{
	CFIndex i;
	CFIndex count = CFDictionaryGetCount(plugin->_browsers);
	NetBrowserInfo* browser = NULL;
	NetBrowserInfo** browsers = malloc(count * sizeof(NetBrowserInfo*));
	
	// Fetch the values of the browser dictionary
	CFDictionaryGetKeysAndValues(plugin->_browsers, (const void**)browsers, NULL);
	
	// Loop thru the browsers list and see if we can find a matching one.
	for (i = 0; i < count; ++i)
	{
		NetBrowserInfo* currentBrowser = browsers[i];
		
		if (currentBrowser->browserRef == sdRef)
		{
			browser = currentBrowser;
			break;
		}
	}
	
	
	free(browsers);

	return browser;
}

/*****************************************************************************
 * AddEventDictionary
 * - 
 * Adds a event to a browser's event dictionary
 *****************************************************************************/

void AddEventDictionary(CFDictionaryRef eventDict, CFMutableDictionaryRef allEventsDictionary, NetBrowserInfo* key)
{
	CFMutableArrayRef eventsForBrowser = (CFMutableArrayRef)CFDictionaryGetValue(allEventsDictionary, key);
	
	if (!eventsForBrowser) // We have no events for this browser yet, lets add him.
	{
		eventsForBrowser = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
		CFDictionarySetValue(allEventsDictionary, key, eventsForBrowser); 
	}
	else 
	{
		CFRetain(eventsForBrowser);
	}

	CFArrayAppendValue(eventsForBrowser, eventDict);
	CFRelease(eventsForBrowser);
}

/*****************************************************************************
 * RemoveEventFromArray
 * - 
 * Searches a Array of Event Dictionaries to find one with a matching launchd
 * token and remove it.
 *****************************************************************************/

void RemoveEventFromArray(CFMutableArrayRef array, CFNumberRef launchdToken)
{
	CFIndex i;
	CFIndex count = CFArrayGetCount(array);
	// Loop thru looking for us.
	for (i = 0; i < count; )
	{
		CFDictionaryRef eventDict = CFArrayGetValueAtIndex(array, i);
		CFNumberRef token = CFDictionaryGetValue(eventDict, sLaunchdTokenKey);
		
		if (CFEqual(token, launchdToken)) // This is the same event?
		{
			CFArrayRemoveValueAtIndex(array, i);	// Remove the event,
			break; // The token should only exist once, so it make no sense to continue.
		}
		else
		{
			++i; // If it's not us, advance.
		}
	}	
}

#pragma mark -
#pragma mark Net Service Browser Stuff
#pragma mark -

/*****************************************************************************
 * ServiceBrowserCallback
 * - 
 * This method is the heart of the plugin. It's the runloop callback annoucing 
 * the appearence and disappearance of network services.
 *****************************************************************************/

void ServiceBrowserCallback (DNSServiceRef				sdRef,
							 DNSServiceFlags            flags,
							 uint32_t                   interfaceIndex,
							 DNSServiceErrorType        errorCode,
							 const char*                serviceName,
							 const char*                regtype,
							 const char*                replyDomain,
							 void*                      context )
{
	(void)interfaceIndex;
	(void)regtype;
	(void)replyDomain;
	BonjourUserEventsPlugin* plugin = (BonjourUserEventsPlugin*)context;
	NetBrowserInfo* browser = BrowserForSDRef(plugin, sdRef);
	
	if (!browser) // Missing browser?
		return;
	
	if (errorCode != kDNSServiceErr_NoError)
		return;
	
	CFStringRef cfServiceName = CFStringCreateWithCString(NULL, serviceName, kCFStringEncodingUTF8);
	
	if (flags & kDNSServiceFlagsAdd)
	{
		HandleTemporaryEventsForService(plugin, browser, cfServiceName, plugin->_onAddEvents);
		HandleStateEventsForService(plugin, browser, cfServiceName, true);
	}
	else 
	{
		HandleTemporaryEventsForService(plugin, browser, cfServiceName, plugin->_onRemoveEvents);
		HandleStateEventsForService(plugin, browser, cfServiceName, false);
	}

	CFRelease(cfServiceName);
}

/*****************************************************************************
 * HandleTemporaryEventsForService
 * - 
 * This method handles the firing of one shot events. Aka. Events that are 
 * signaled when a service appears / disappears. They have a temporarly 
 * signaled state. 
 *****************************************************************************/
void HandleTemporaryEventsForService(BonjourUserEventsPlugin* plugin, NetBrowserInfo* browser, CFStringRef serviceName, CFMutableDictionaryRef eventsDictionary)
{
	CFArrayRef events = (CFArrayRef)CFDictionaryGetValue(eventsDictionary, browser); // Get events for the browser we passed in.
	CFIndex i;
	CFIndex count;
	
	if (!events)  // Somehow we have a orphan browser...
		return;
	
	count = CFArrayGetCount(events);
	
	// Go thru the events and run filters, notifity if they pass.
	for (i = 0; i < count; ++i)
	{
		CFDictionaryRef eventDict = (CFDictionaryRef)CFArrayGetValueAtIndex(events, i);
		CFStringRef eventServiceName = (CFStringRef)CFDictionaryGetValue(eventDict, sServiceNameKey);
		CFNumberRef token = (CFNumberRef) CFDictionaryGetValue(eventDict, sLaunchdTokenKey);
				
		// Currently we only filter on service name, that makes this as simple as... 
		if (!eventServiceName || CFEqual(serviceName, eventServiceName))
		{
			// Create Context Info
			CFRunLoopTimerContext context; 
			TimerContextInfo* info = TimerContextInfoCreate(plugin, token);

			context.version = 0;
			context.info = info;
			context.retain = TimerContextInfoRetain;
			context.release = TimerContextInfoRelease;
			context.copyDescription = TimerContextInfoCopyDescription;
			
			// Create and add one shot timer to flip the event off after a second
			CFRunLoopTimerRef timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + 1.0, 0, 0, 0, TemporaryEventTimerCallout, &context);
			CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);
			
			// Signal Event
			UserEventAgentSetLaunchEventState(plugin->_pluginContext, token, true);
			
			// Clean Up
			TimerContextInfoRelease(info);
			CFRelease(timer);
			
		}
	}
	
}

/*****************************************************************************
 * HandleStateEventsForService
 * - 
 * This method handles the toggling the state of a while exists event to 
 * reflect the network. 
 *****************************************************************************/
void HandleStateEventsForService(BonjourUserEventsPlugin* plugin, NetBrowserInfo* browser, CFStringRef serviceName, Boolean didAppear)
{
	CFArrayRef events = (CFArrayRef)CFDictionaryGetValue(plugin->_whileServiceExist, browser); // Get the _whileServiceExist events that are interested in this browser.
	CFIndex i;
	CFIndex count;
	
	if (!events)  // Somehow we have a orphan browser...
		return;
	
	count = CFArrayGetCount(events);
	
	// Go thru the events and run filters, notifity if they pass.
	for (i = 0; i < count; ++i)
	{
		CFDictionaryRef eventDict = (CFDictionaryRef)CFArrayGetValueAtIndex(events, i);
		CFStringRef eventServiceName = (CFStringRef)CFDictionaryGetValue(eventDict, sServiceNameKey);
		CFNumberRef token = (CFNumberRef) CFDictionaryGetValue(eventDict, sLaunchdTokenKey);
		
		// Currently we only filter on service name, that makes this as simple as... 
		if (!eventServiceName || CFEqual(serviceName, eventServiceName))
			UserEventAgentSetLaunchEventState(plugin->_pluginContext, token, didAppear);
	}
}

/*****************************************************************************
 * TemporaryEventTimerCallout
 * - 
 * This method is invoked a second after a watched service appears / disappears
 * to toggle the state of the launch event back to false.
 *****************************************************************************/
void TemporaryEventTimerCallout ( CFRunLoopTimerRef timer, void *info )
{
	TimerContextInfo* contextInfo = (TimerContextInfo*)info;

	UserEventAgentSetLaunchEventState(contextInfo->plugin->_pluginContext, contextInfo->token, false);
	
	// Remove from pending timers array.
	CFIndex i;
	CFIndex count = CFArrayGetCount(contextInfo->plugin->_timers);
	
	for (i = 0; i < count; ++i)
	{
		CFRunLoopTimerRef item = (CFRunLoopTimerRef)CFArrayGetValueAtIndex(contextInfo->plugin->_timers, i);
		
		if (item == timer)
			break;
	}
	
	if (i != count)
		CFArrayRemoveValueAtIndex(contextInfo->plugin->_timers, i);
}

#pragma mark -
#pragma mark Convenence
#pragma mark -

/*****************************************************************************
 * CStringFromCFString
 * - 
 * Silly convenence function for dealing with non-critical CFSTR -> cStr
 * conversions.
 *****************************************************************************/

const char* CStringFromCFString(CFStringRef string)
{
	const char* defaultString = "??????";
	const char* cstring;

	if (!string)
		return defaultString;
	
	cstring = CFStringGetCStringPtr(string, kCFStringEncodingUTF8);
	
	return (cstring) ? cstring : defaultString;
	
}

#pragma mark -
#pragma mark TimerContextInfo "Object"
#pragma mark -

/*****************************************************************************
 * TimerContextInfoCreate
 * - 
 * Convenence for creating TimerContextInfo pseudo-objects
 *****************************************************************************/
TimerContextInfo* TimerContextInfoCreate(BonjourUserEventsPlugin* plugin, CFNumberRef token)
{
	TimerContextInfo* info = malloc(sizeof(TimerContextInfo));
	
	info->refCount = 1;
	info->plugin = plugin;
	info->token = (CFNumberRef)CFRetain(token);
	
	return info;
}

/*****************************************************************************
 * TimerContextInfoRetain
 * - 
 * Convenence for retaining TimerContextInfo pseudo-objects
 *****************************************************************************/
const void* TimerContextInfoRetain(const void* info)
{
	TimerContextInfo* context = (TimerContextInfo*)info;
	
	if (!context)
		return NULL;
	
	++context->refCount;
	
	return context;
}

/*****************************************************************************
 * TimerContextInfoRelease
 * - 
 * Convenence for releasing TimerContextInfo pseudo-objects
 *****************************************************************************/
void TimerContextInfoRelease(const void* info)
{
	TimerContextInfo* context = (TimerContextInfo*)info;
	
	if (!context)
		return;
	
	if (context->refCount == 1)
	{
		CFRelease(context->token);
		free(context);
		return;
	}
	else 
	{
		--context->refCount;
	}
}

/*****************************************************************************
 * TimerContextInfoCopyDescription
 * - 
 * This method actually does nothing, but is just a stub so CF is happy.
 *****************************************************************************/
CFStringRef TimerContextInfoCopyDescription(const void* info)
{
	(void)info;
	return CFStringCreateWithCString(NULL, "TimerContextInfo: No useful description", kCFStringEncodingUTF8);
}


#pragma mark -
#pragma mark NetBrowserInfo "Object"
#pragma mark -
/*****************************************************************************
 * NetBrowserInfoCreate
 * - 
 * The method creates a NetBrowserInfo Object and initalizes it.
 *****************************************************************************/
NetBrowserInfo* NetBrowserInfoCreate(CFStringRef serviceType, CFStringRef domain, void* context)
{
	NetBrowserInfo* outObj = NULL;
	DNSServiceRef browserRef = NULL;
	char* cServiceType = NULL;
	char* cDomain = NULL;
	Boolean success = true;
	
	CFIndex serviceSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(serviceType), kCFStringEncodingUTF8);
	cServiceType = calloc(serviceSize, 1);
	success = CFStringGetCString(serviceType, cServiceType, serviceSize, kCFStringEncodingUTF8);
	
	if (domain)
	{
		CFIndex domainSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(domain), kCFStringEncodingUTF8);
		cDomain = calloc(serviceSize, 1);
		success = success && CFStringGetCString(domain, cDomain, domainSize, kCFStringEncodingUTF8);
	}
	
	if (!success)
	{
		fprintf(stderr, "LaunchEvent has badly encoded service type or domain.\n");
		free(cServiceType);

		if (cDomain)
			free(cDomain);
		
		return NULL;
	}
	
	DNSServiceErrorType err = DNSServiceBrowse(&browserRef, 0, 0, cServiceType, cDomain, ServiceBrowserCallback, context);

	if (err != kDNSServiceErr_NoError)
	{
		fprintf(stderr, "Failed to create browser for %s, %s\n", cServiceType, cDomain);
		free(cServiceType);
		
		if (cDomain)
			free(cDomain);
		
		return NULL;
	}

	DNSServiceSetDispatchQueue(browserRef, dispatch_get_main_queue());
	
	
	outObj = malloc(sizeof(NetBrowserInfo));
	
	outObj->refCount = 1;
	outObj->browserRef = browserRef;

	free(cServiceType);
								  
	if (cDomain)
		free(cDomain);
	
	return outObj;
}

/*****************************************************************************
 * NetBrowserInfoRetain
 * - 
 * The method retains a NetBrowserInfo object.
 *****************************************************************************/
const void* NetBrowserInfoRetain(CFAllocatorRef allocator, const void* info)
{
	(void)allocator;
	NetBrowserInfo* obj = (NetBrowserInfo*)info;
	
	if (!obj) 
		return NULL;
	
	++obj->refCount;
	
	return obj;
}

/*****************************************************************************
 * NetBrowserInfoRelease
 * - 
 * The method releases a NetBrowserInfo object.
 *****************************************************************************/
void NetBrowserInfoRelease(CFAllocatorRef allocator, const void* info)
{
	(void)allocator;
	NetBrowserInfo* obj = (NetBrowserInfo*)info;
	
	if (!obj)
		return;
	
	if (obj->refCount == 1)
	{
		DNSServiceRefDeallocate(obj->browserRef);
		free(obj);
	}
	else 
	{
		--obj->refCount;
	}

}

/*****************************************************************************
 * NetBrowserInfoEqual
 * - 
 * The method is used to compare two NetBrowserInfo objects for equality.
 *****************************************************************************/
Boolean	NetBrowserInfoEqual(const void *value1, const void *value2)
{
	NetBrowserInfo* obj1 = (NetBrowserInfo*)value1;
	NetBrowserInfo* obj2 = (NetBrowserInfo*)value2;
	
	if (obj1->browserRef == obj2->browserRef)
		return true;
	
	return false;
}

/*****************************************************************************
 * NetBrowserInfoHash
 * - 
 * The method is used to make a hash for the object. We can cheat and use the 
 * browser pointer.
 *****************************************************************************/
CFHashCode	NetBrowserInfoHash(const void *value)
{
	return (CFHashCode)((NetBrowserInfo*)value)->browserRef;
}


/*****************************************************************************
 * NetBrowserInfoCopyDescription
 * - 
 * Make CF happy.
 *****************************************************************************/
CFStringRef	NetBrowserInfoCopyDescription(const void *value)
{
	(void)value;
	return CFStringCreateWithCString(NULL, "NetBrowserInfo: No useful description", kCFStringEncodingUTF8);
}