// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h"

#include <cstring>

@implementation FlutterBinaryCodec
+ (instancetype)sharedInstance {
  static id _sharedInstance = nil;
  if (!_sharedInstance) {
    _sharedInstance = [[FlutterBinaryCodec alloc] init];
  }
  return _sharedInstance;
}

- (NSData*)encode:(id)message {
  NSAssert(!message || [message isKindOfClass:[NSData class]], @"");
  return message;
}

- (NSData*)decode:(NSData*)message {
  return message;
}
@end

@implementation FlutterStringCodec
+ (instancetype)sharedInstance {
  static id _sharedInstance = nil;
  if (!_sharedInstance) {
    _sharedInstance = [[FlutterStringCodec alloc] init];
  }
  return _sharedInstance;
}

- (NSData*)encode:(id)message {
  if (message == nil) {
    return nil;
  }
  NSAssert([message isKindOfClass:[NSString class]], @"");
  NSString* stringMessage = message;
  const char* utf8 = stringMessage.UTF8String;
  return [NSData dataWithBytes:utf8 length:strlen(utf8)];
}

- (NSString*)decode:(NSData*)message {
  if (message == nil) {
    return nil;
  }
  return [[[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding] autorelease];
}
@end

@implementation FlutterJSONMessageCodec
+ (instancetype)sharedInstance {
  static id _sharedInstance = nil;
  if (!_sharedInstance) {
    _sharedInstance = [[FlutterJSONMessageCodec alloc] init];
  }
  return _sharedInstance;
}

- (NSData*)encode:(id)message {
  if (message == nil) {
    return nil;
  }
  NSData* encoding;
  if ([message isKindOfClass:[NSArray class]] || [message isKindOfClass:[NSDictionary class]]) {
    encoding = [NSJSONSerialization dataWithJSONObject:message options:0 error:nil];
  } else {
    // NSJSONSerialization does not support top-level simple values.
    // We encode as singleton array, then extract the relevant bytes.
    encoding = [NSJSONSerialization dataWithJSONObject:@[ message ] options:0 error:nil];
    if (encoding) {
      encoding = [encoding subdataWithRange:NSMakeRange(1, encoding.length - 2)];
    }
  }
  NSAssert(encoding, @"Invalid JSON message, encoding failed");
  return encoding;
}

- (id)decode:(NSData*)message {
  if ([message length] == 0) {
    return nil;
  }
  BOOL isSimpleValue = NO;
  id decoded = nil;
  if (0 < message.length) {
    UInt8 first;
    [message getBytes:&first length:1];
    isSimpleValue = first != '{' && first != '[';
    if (isSimpleValue) {
      // NSJSONSerialization does not support top-level simple values.
      // We expand encoding to singleton array, then decode that and extract
      // the single entry.
      UInt8 begin = '[';
      UInt8 end = ']';
      NSMutableData* expandedMessage = [NSMutableData dataWithLength:message.length + 2];
      [expandedMessage replaceBytesInRange:NSMakeRange(0, 1) withBytes:&begin];
      [expandedMessage replaceBytesInRange:NSMakeRange(1, message.length) withBytes:message.bytes];
      [expandedMessage replaceBytesInRange:NSMakeRange(message.length + 1, 1) withBytes:&end];
      message = expandedMessage;
    }
    decoded = [NSJSONSerialization JSONObjectWithData:message options:0 error:nil];
  }
  NSAssert(decoded, @"Invalid JSON message, decoding failed");
  return isSimpleValue ? ((NSArray*)decoded)[0] : decoded;
}
@end

@implementation FlutterJSONMethodCodec
+ (instancetype)sharedInstance {
  static id _sharedInstance = nil;
  if (!_sharedInstance) {
    _sharedInstance = [[FlutterJSONMethodCodec alloc] init];
  }
  return _sharedInstance;
}

- (NSData*)encodeMethodCall:(FlutterMethodCall*)call {
  return [[FlutterJSONMessageCodec sharedInstance] encode:@{
    @"method" : call.method,
    @"args" : [self wrapNil:call.arguments],
  }];
}

- (NSData*)encodeSuccessEnvelope:(id)result {
  return [[FlutterJSONMessageCodec sharedInstance] encode:@[ [self wrapNil:result] ]];
}

- (NSData*)encodeErrorEnvelope:(FlutterError*)error {
  return [[FlutterJSONMessageCodec sharedInstance] encode:@[
    error.code,
    [self wrapNil:error.message],
    [self wrapNil:error.details],
  ]];
}

- (FlutterMethodCall*)decodeMethodCall:(NSData*)message {
  NSDictionary* dictionary = [[FlutterJSONMessageCodec sharedInstance] decode:message];
  id method = dictionary[@"method"];
  id arguments = [self unwrapNil:dictionary[@"args"]];
  NSAssert([method isKindOfClass:[NSString class]], @"Invalid JSON method call");
  return [FlutterMethodCall methodCallWithMethodName:method arguments:arguments];
}

- (id)decodeEnvelope:(NSData*)envelope {
  NSArray* array = [[FlutterJSONMessageCodec sharedInstance] decode:envelope];
  if (array.count == 1) {
    return [self unwrapNil:array[0]];
  }
  NSAssert(array.count == 3, @"Invalid JSON envelope");
  id code = array[0];
  id message = [self unwrapNil:array[1]];
  id details = [self unwrapNil:array[2]];
  NSAssert([code isKindOfClass:[NSString class]], @"Invalid JSON envelope");
  NSAssert(message == nil || [message isKindOfClass:[NSString class]], @"Invalid JSON envelope");
  return [FlutterError errorWithCode:code message:message details:details];
}

- (id)wrapNil:(id)value {
  return value == nil ? [NSNull null] : value;
}
- (id)unwrapNil:(id)value {
  return value == [NSNull null] ? nil : value;
}
@end
