
#import "ABRouter.h"

@implementation ABRouter

@synthesize verbose, delegate;

- (id)initWithName:(NSString*)name
{
    self = [super init];
    if (self) {
        self.verbose = NO;
        _name = [name retain];
        _components = [[NSMutableDictionary dictionaryWithCapacity:4] retain];
        _jsonParser = [[[SBJsonParser alloc] init] retain];
        _jsonWriter = [[[SBJsonWriter alloc] init] retain];
        _nextId = 0;
    }
    return self;
}

- (void) sendEvent:(NSString*)method to:(NSString*)to info:(NSDictionary*)info
{
    if (verbose) {
        NSLog(@"[ABRouter] sendEvent:%@", method);
    }
    if (info == NULL) {
        info = [NSDictionary dictionary];
    }
    NSDictionary *event = [NSDictionary dictionaryWithObjectsAndKeys:
                                [self _newId],  @"id",
                                _name,          @"from",
                                to,             @"to",
                                method,         @"method",
                                info,           @"info",
                                nil];
    [self _processEvent:event];
}

- (void) _registerComponent:(id<ABWrapper>)subprocess
{
    [_components setObject:subprocess forKey:[subprocess _getName]];
    if (verbose) {
        NSLog(@"[ABRouter %@] registered component '%@'", self, [subprocess _getName]);
    }
}

- (void) _subprocess:(id<ABWrapper>)subprocess gotStderrText:(NSString*)text;
{
    if (self.verbose) {
        NSLog(@"[AB][%@ STDERR] %@", [subprocess _getName], text);
    }
}

- (void) _subprocessTerminated:(id<ABWrapper>)subprocess
{
    if (self.verbose) {
        NSLog(@"[AB][%@] terminated.", [subprocess _getName]);
    }
}

- (void) _processEventJson:(NSString*)json
{
    [self _processEvent:(NSDictionary*)[_jsonParser objectWithString:json]];
}

- (void) _processEvent:(NSDictionary*)event
{
    NSString *json = [_jsonWriter stringWithObject:event];
    NSString *to = (NSString*)[event objectForKey:@"to"];
    if (verbose) {
        NSLog(@"[ABRouter] _processEvent to:'%@'", to);
    }
    if ([to compare:_name] == NSOrderedSame) {
        [delegate handleABEvent:[[ABEvent alloc] _initWithRouter:self event:event]];
    }
    else {
        id<ABWrapper> component = (id<ABWrapper>)([_components objectForKey:to]);
        [component _sendEventJson:json];
    }
}

- (NSNumber*) _newId
{
    long i = _nextId;
    _nextId++;
    return [NSNumber numberWithLong:i];
}

- (void) dealloc
{
    [_components release];
}

@end
