/*
 Copyright (c) 2010, Stig Brautaset.
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:

   Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

   Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

   Neither the name of the the author nor the names of its contributors
   may be used to endorse or promote products derived from this software
   without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "SBJsonStreamWriter.h"
#import "SBJsonStreamWriterState.h"

static NSNumber *kNotANumber;
static NSNumber *kTrue;
static NSNumber *kFalse;
static NSNumber *kPositiveInfinity;
static NSNumber *kNegativeInfinity;


@implementation SBJsonStreamWriter

@synthesize error;
@synthesize maxDepth;
@synthesize state;
@synthesize stateStack;
@synthesize humanReadable;
@synthesize sortKeys;
@synthesize sortKeysComparator;

+ (void)initialize {
	kNotANumber = [NSDecimalNumber notANumber];
    kPositiveInfinity = [NSNumber numberWithDouble:+INFINITY];
    kNegativeInfinity = [NSNumber numberWithDouble:-INFINITY];
    kTrue = [NSNumber numberWithBool:YES];
    kFalse = [NSNumber numberWithBool:NO];
}

#pragma mark Housekeeping

@synthesize delegate;

- (id)init {
	self = [super init];
	if (self) {
		maxDepth = 32u;
        stateStack = [[NSMutableArray alloc] initWithCapacity:maxDepth];
        state = [SBJsonStreamWriterStateStart sharedInstance];
        cache = [[NSMutableDictionary alloc] initWithCapacity:32];
    }
	return self;
}

- (void)dealloc {
    self.state = nil;
}

#pragma mark Methods

- (void)appendBytes:(const void *)bytes length:(NSUInteger)length {
    [delegate writer:self appendBytes:bytes length:length];
}

- (BOOL)writeObject:(NSDictionary *)dict {
	if (![self writeObjectOpen])
		return NO;

	NSArray *keys = [dict allKeys];
	
	if (sortKeys) {
		if (sortKeysComparator) {
			keys = [keys sortedArrayWithOptions:NSSortStable usingComparator:sortKeysComparator];
		}
		else{
			keys = [keys sortedArrayUsingSelector:@selector(compare:)];
		}
	}

	for (id k in keys) {
		if (![k isKindOfClass:[NSString class]]) {
			self.error = [NSString stringWithFormat:@"JSON object key must be string: %@", k];
			return NO;
		}

		if (![self writeString:k])
			return NO;
		if (![self writeValue:[dict objectForKey:k]])
			return NO;
	}

	return [self writeObjectClose];
}

- (BOOL)writeArray:(NSArray*)array {
	if (![self writeArrayOpen])
		return NO;
	for (id v in array)
		if (![self writeValue:v])
			return NO;
	return [self writeArrayClose];
}


- (BOOL)writeObjectOpen {
	if ([state isInvalidState:self]) return NO;
	if ([state expectingKey:self]) return NO;
	[state appendSeparator:self];
	if (humanReadable && stateStack.count) [state appendWhitespace:self];

    [stateStack addObject:state];
    self.state = [SBJsonStreamWriterStateObjectStart sharedInstance];

	if (maxDepth && stateStack.count > maxDepth) {
		self.error = @"Nested too deep";
		return NO;
	}

	[delegate writer:self appendBytes:"{" length:1];
	return YES;
}

- (BOOL)writeObjectClose {
	if ([state isInvalidState:self]) return NO;

    SBJsonStreamWriterState *prev = state;

    self.state = [stateStack lastObject];
    [stateStack removeLastObject];

	if (humanReadable) [prev appendWhitespace:self];
	[delegate writer:self appendBytes:"}" length:1];

	[state transitionState:self];
	return YES;
}

- (BOOL)writeArrayOpen {
	if ([state isInvalidState:self]) return NO;
	if ([state expectingKey:self]) return NO;
	[state appendSeparator:self];
	if (humanReadable && stateStack.count) [state appendWhitespace:self];

    [stateStack addObject:state];
	self.state = [SBJsonStreamWriterStateArrayStart sharedInstance];

	if (maxDepth && stateStack.count > maxDepth) {
		self.error = @"Nested too deep";
		return NO;
	}

	[delegate writer:self appendBytes:"[" length:1];
	return YES;
}

- (BOOL)writeArrayClose {
	if ([state isInvalidState:self]) return NO;
	if ([state expectingKey:self]) return NO;

    SBJsonStreamWriterState *prev = state;

    self.state = [stateStack lastObject];
    [stateStack removeLastObject];

	if (humanReadable) [prev appendWhitespace:self];
	[delegate writer:self appendBytes:"]" length:1];

	[state transitionState:self];
	return YES;
}

- (BOOL)writeNull {
	if ([state isInvalidState:self]) return NO;
	if ([state expectingKey:self]) return NO;
	[state appendSeparator:self];
	if (humanReadable) [state appendWhitespace:self];

	[delegate writer:self appendBytes:"null" length:4];
	[state transitionState:self];
	return YES;
}

- (BOOL)writeBool:(BOOL)x {
	if ([state isInvalidState:self]) return NO;
	if ([state expectingKey:self]) return NO;
	[state appendSeparator:self];
	if (humanReadable) [state appendWhitespace:self];

	if (x)
		[delegate writer:self appendBytes:"true" length:4];
	else
		[delegate writer:self appendBytes:"false" length:5];
	[state transitionState:self];
	return YES;
}


- (BOOL)writeValue:(id)o {
	if ([o isKindOfClass:[NSDictionary class]]) {
		return [self writeObject:o];

	} else if ([o isKindOfClass:[NSArray class]]) {
		return [self writeArray:o];

	} else if ([o isKindOfClass:[NSString class]]) {
		[self writeString:o];
		return YES;

	} else if ([o isKindOfClass:[NSNumber class]]) {
		return [self writeNumber:o];

	} else if ([o isKindOfClass:[NSNull class]]) {
		return [self writeNull];

	} else if ([o respondsToSelector:@selector(proxyForJson)]) {
		return [self writeValue:[o proxyForJson]];

	}

	self.error = [NSString stringWithFormat:@"JSON serialisation not supported for %@", [o class]];
	return NO;
}

static const char *strForChar(int c) {
	switch (c) {
		case 0: return "\\u0000"; break;
		case 1: return "\\u0001"; break;
		case 2: return "\\u0002"; break;
		case 3: return "\\u0003"; break;
		case 4: return "\\u0004"; break;
		case 5: return "\\u0005"; break;
		case 6: return "\\u0006"; break;
		case 7: return "\\u0007"; break;
		case 8: return "\\b"; break;
		case 9: return "\\t"; break;
		case 10: return "\\n"; break;
		case 11: return "\\u000b"; break;
		case 12: return "\\f"; break;
		case 13: return "\\r"; break;
		case 14: return "\\u000e"; break;
		case 15: return "\\u000f"; break;
		case 16: return "\\u0010"; break;
		case 17: return "\\u0011"; break;
		case 18: return "\\u0012"; break;
		case 19: return "\\u0013"; break;
		case 20: return "\\u0014"; break;
		case 21: return "\\u0015"; break;
		case 22: return "\\u0016"; break;
		case 23: return "\\u0017"; break;
		case 24: return "\\u0018"; break;
		case 25: return "\\u0019"; break;
		case 26: return "\\u001a"; break;
		case 27: return "\\u001b"; break;
		case 28: return "\\u001c"; break;
		case 29: return "\\u001d"; break;
		case 30: return "\\u001e"; break;
		case 31: return "\\u001f"; break;
		case 34: return "\\\""; break;
		case 92: return "\\\\"; break;
	}
	NSLog(@"FUTFUTFUT: -->'%c'<---", c);
	return "FUTFUTFUT";
}

- (BOOL)writeString:(NSString*)string {
	if ([state isInvalidState:self]) return NO;
	[state appendSeparator:self];
	if (humanReadable) [state appendWhitespace:self];

	NSMutableData *buf = [cache objectForKey:string];
	if (!buf) {

        NSUInteger len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
        const char *utf8 = [string UTF8String];
        NSUInteger written = 0, i = 0;

        buf = [NSMutableData dataWithCapacity:(NSUInteger)(len * 1.1f)];
        [buf appendBytes:"\"" length:1];

        for (i = 0; i < len; i++) {
            int c = utf8[i];
            BOOL isControlChar = c >= 0 && c < 32;
            if (isControlChar || c == '"' || c == '\\') {
                if (i - written)
                    [buf appendBytes:utf8 + written length:i - written];
                written = i + 1;

                const char *t = strForChar(c);
                [buf appendBytes:t length:strlen(t)];
            }
        }

        if (i - written)
            [buf appendBytes:utf8 + written length:i - written];

        [buf appendBytes:"\"" length:1];
        [cache setObject:buf forKey:string];
    }

	[delegate writer:self appendBytes:[buf bytes] length:[buf length]];
	[state transitionState:self];
	return YES;
}

- (BOOL)writeNumber:(NSNumber*)number {
	if (number == kTrue || number == kFalse)
		return [self writeBool:[number boolValue]];

	if ([state isInvalidState:self]) return NO;
	if ([state expectingKey:self]) return NO;
	[state appendSeparator:self];
	if (humanReadable) [state appendWhitespace:self];

	if ([kPositiveInfinity isEqualToNumber:number]) {
		self.error = @"+Infinity is not a valid number in JSON";
		return NO;

	} else if ([kNegativeInfinity isEqualToNumber:number]) {
		self.error = @"-Infinity is not a valid number in JSON";
		return NO;

	} else if ([kNotANumber isEqualToNumber:number]) {
		self.error = @"NaN is not a valid number in JSON";
		return NO;
	}

	const char *objcType = [number objCType];
	char num[128];
	size_t len;

	switch (objcType[0]) {
		case 'c': case 'i': case 's': case 'l': case 'q':
			len = snprintf(num, sizeof num, "%lld", [number longLongValue]);
			break;
		case 'C': case 'I': case 'S': case 'L': case 'Q':
			len = snprintf(num, sizeof num, "%llu", [number unsignedLongLongValue]);
			break;
		case 'f': case 'd': default:
			if ([number isKindOfClass:[NSDecimalNumber class]]) {
				char const *utf8 = [[number stringValue] UTF8String];
				[delegate writer:self appendBytes:utf8 length: strlen(utf8)];
				[state transitionState:self];
				return YES;
			}
			len = snprintf(num, sizeof num, "%.17g", [number doubleValue]);
			break;
	}
	[delegate writer:self appendBytes:num length: len];
	[state transitionState:self];
	return YES;
}

@end
