#import <folly/dynamic.h>

static id ConvertDynamicToNSObject(const folly::dynamic &dynamic);

static NSDictionary *ConvertDynamicToNSDictionary(const folly::dynamic &dynamic) {
  if (!dynamic.isObject()) {
    return nil;
  }
  NSMutableDictionary *dict = [NSMutableDictionary dictionary];
  for (auto &item : dynamic.items()) {
    NSString *key = [NSString stringWithUTF8String:item.first.asString().c_str()];
    id value = ConvertDynamicToNSObject(item.second);
    if (key && value) {
      dict[key] = value;
    }
  }
  return dict;
}

static id ConvertDynamicToNSObject(const folly::dynamic &dynamic) {
  switch (dynamic.type()) {
    case folly::dynamic::Type::NULLT:
      return [NSNull null];
    case folly::dynamic::Type::BOOL:
      return [NSNumber numberWithBool:dynamic.getBool()];
    case folly::dynamic::Type::DOUBLE:
      return [NSNumber numberWithDouble:dynamic.getDouble()];
    case folly::dynamic::Type::INT64:
      return [NSNumber numberWithLongLong:dynamic.getInt()];
    case folly::dynamic::Type::STRING:
      return [NSString stringWithUTF8String:dynamic.getString().c_str()];
    case folly::dynamic::Type::ARRAY: {
      NSMutableArray *arr = [NSMutableArray array];
      for (auto &item : dynamic) {
        [arr addObject:ConvertDynamicToNSObject(item) ?: [NSNull null]];
      }
      return arr;
    }
    case folly::dynamic::Type::OBJECT:
      return ConvertDynamicToNSDictionary(dynamic);
    default:
      return nil;
  }
}
