//
//  MCSServiceResolver.h
//  BPClientTest
//
//  Created by Michael Clark on 10-02-27.
//  Copyright 2010 Marketcircle, Inc. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "MCSServiceTracker.h"

@class MCSService;



#pragma mark -
#pragma mark Abstract Resolver
@interface MCSServiceResolver : NSObject {
    NSString*             serviceName;
    
    id                    resolutionDelegate;
}
@property (nonatomic,readonly,retain) NSString* serviceName;
@property (nonatomic,readonly,assign) id  resolutionDelegate;

- (id)initWithServiceName: (NSString*)aName resolutionDelegate: (id)aResolutionDelegate;

// Subclassers override these to start/stop doing their work
- (void)start;
- (void)stop;

- (MCSServiceResolveScope)resolveScope;

@end


#pragma mark -
#pragma mark ResolverDelegate
@interface NSObject (MCSServiceResolverDelegate)

- (void)serviceResolverWillBeginResolve: (MCSServiceResolver*)resolver;
- (void)serviceResolver: (MCSServiceResolver*)resolver resolvedService: (MCSService*)aService;
- (void)serviceResolverDidFinish: (MCSServiceResolver*)resolver;
- (void)serviceResolver: (MCSServiceResolver*)resolver didNotResolve: (NSError*)error;

// Bonjour specifc
- (void)serviceResolver: (MCSServiceResolver*)resolver lostService: (MCSService*)aService;

@end



#pragma mark -
#pragma mark Local Resolver
#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_4_0
@interface MCSLocalServiceResolver : MCSServiceResolver
#else
@interface MCSLocalServiceResolver : MCSServiceResolver<NSNetServiceBrowserDelegate, NSNetServiceDelegate>
#endif
{
    NSString*    bonjourServiceName;
    
    NSNetServiceBrowser* serviceBrowser;
    NSMutableArray*      foundNetServices;
    NSMutableArray*      lostNetServices;

    NSMutableDictionary*  serviceCache;
}
@property (nonatomic,readonly,retain) NSString*    bonjourServiceName;

- (id)initWithServiceName: (NSString*)aName resolutionDelegate: (id)aResolutionDelegate bonjourServiceName: (NSString*)aName;

@end



#pragma mark -
#pragma mark Remote Resolver
@interface MCSRemoteServiceResolver : MCSServiceResolver {
    NSString*    remoteAddress;
    NSUInteger   remotePort;
	NSString*	 cloudAccount;
}
@property (nonatomic,readonly,retain) NSString*    remoteAddress;
@property (nonatomic,readonly,assign) NSUInteger   remotePort;
@property (nonatomic,readonly,retain) NSString*	   cloudAccount;

- (id)initWithServiceName: (NSString*)aName resolutionDelegate: (id)aResolutionDelegate remoteAddress: (NSString*)anAddress remotePort: (NSUInteger)aPort;
- (id)initWithServiceName: (NSString*)aName resolutionDelegate: (id)aResolutionDelegate remoteAddress: (NSString*)anAddress remotePort: (NSUInteger)aPort cloudAccount:(NSString *)cloudAccount;
@end


@class MCCDiscoveryHelper;

#pragma mark -
#pragma mark Cloud Resolver

// Error Codes
typedef enum {
	kMCSCloudResolverUnknownError,
	kMCSCloudResolverCloudDownError,
    kMCSCloudResolverAccountDNEError, // Account Does Not Exist
    kMCSCloudResolverAuthError,
    kMCSCloudResolverDestinationServerDownError
} MCSCloudResolverErrorCode;

extern NSString* kMCSCloudResolverErrorDomain;

#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_4_0
@interface MCSCloudServiceResolver : MCSServiceResolver
#else
#import <MCCloud/MCCDiscoveryHelperDelegate.h>
@interface MCSCloudServiceResolver : MCSServiceResolver <MCCDiscoveryHelperDelegate, NSNetServiceBrowserDelegate, NSNetServiceDelegate>
#endif
{
    NSString*   cloudAccount;
    NSString*   appUserName;
    NSString*   appPassword;
    NSString*   databaseName;
    NSNumber*   schemaVersion;
    
    MCCDiscoveryHelper*  cloudResolver;
}
@property (nonatomic,readonly,retain) NSString*   cloudAccount;
@property (nonatomic,readonly,retain) NSString*   appUserName;
@property (nonatomic,readonly,retain) NSString*   appPassword;
@property(nonatomic,readonly,retain)NSString *databaseName;
@property(nonatomic,readonly,retain)NSNumber *schemaVersion;


- (id)initWithServiceName: (NSString*)aName resolutionDelegate: (id)aResoltionDelegate cloudAccount: (NSString*)anAccount applicationUserName: (NSString*)aUserName password: (NSString*)aPassword databaseName: (NSString*)aDatabaseName schemaVersion: (NSNumber*)aSchemaVersion;

@end






