// 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.

#include "flutter/shell/platform/darwin/common/framework/Source/FlutterStandardCodecHelper.h"
#include <stdint.h>

#include <vector>

#include "flutter/fml/logging.h"

// The google-runtime-int lint suggests uint64_t in place of unsigned long,
// however these functions are frequently used with NSUInteger, which is
// defined as an unsigned long.
//
// NOLINTBEGIN(google-runtime-int)

void FlutterStandardCodecHelperReadAlignment(unsigned long* location,
                                             uint8_t alignment) {
  uint8_t mod = *location % alignment;
  if (mod) {
    *location += (alignment - mod);
  }
}

static uint8_t PeekByte(unsigned long location, CFDataRef data) {
  uint8_t result;
  CFRange range = CFRangeMake(location, 1);
  CFDataGetBytes(data, range, &result);
  return result;
}

void FlutterStandardCodecHelperReadBytes(unsigned long* location,
                                         unsigned long length,
                                         void* destination,
                                         CFDataRef data) {
  CFRange range = CFRangeMake(*location, length);
  CFDataGetBytes(data, range, static_cast<UInt8*>(destination));
  *location += length;
}

uint8_t FlutterStandardCodecHelperReadByte(unsigned long* location,
                                           CFDataRef data) {
  uint8_t value;
  FlutterStandardCodecHelperReadBytes(location, 1, &value, data);
  return value;
}

uint32_t FlutterStandardCodecHelperReadSize(unsigned long* location,
                                            CFDataRef data) {
  uint8_t byte = FlutterStandardCodecHelperReadByte(location, data);
  if (byte < 254) {
    return (uint32_t)byte;
  } else if (byte == 254) {
    UInt16 value;
    FlutterStandardCodecHelperReadBytes(location, 2, &value, data);
    return value;
  } else {
    UInt32 value;
    FlutterStandardCodecHelperReadBytes(location, 4, &value, data);
    return value;
  }
}

static CFDataRef ReadDataNoCopy(unsigned long* location,
                                unsigned long length,
                                CFDataRef data) {
  CFDataRef result = CFDataCreateWithBytesNoCopy(
      kCFAllocatorDefault, CFDataGetBytePtr(data) + *location, length,
      kCFAllocatorNull);
  *location += length;
  return static_cast<CFDataRef>(CFAutorelease(result));
}

CFStringRef FlutterStandardCodecHelperReadUTF8(unsigned long* location,
                                               CFDataRef data) {
  uint32_t size = FlutterStandardCodecHelperReadSize(location, data);
  CFDataRef bytes = ReadDataNoCopy(location, size, data);
  CFStringRef result = CFStringCreateFromExternalRepresentation(
      kCFAllocatorDefault, bytes, kCFStringEncodingUTF8);
  return static_cast<CFStringRef>(CFAutorelease(result));
}

// Peeks ahead to see if we are reading a standard type.  If so, recurse
// directly to FlutterStandardCodecHelperReadValueOfType, otherwise recurse to
// objc.
static inline CFTypeRef FastReadValue(
    unsigned long* location,
    CFDataRef data,
    CFTypeRef (*ReadValue)(CFTypeRef),
    CFTypeRef (*ReadTypedDataOfType)(FlutterStandardField, CFTypeRef),
    CFTypeRef user_data) {
  uint8_t type = PeekByte(*location, data);
  if (FlutterStandardFieldIsStandardType(type)) {
    *location += 1;
    return FlutterStandardCodecHelperReadValueOfType(
        location, data, type, ReadValue, ReadTypedDataOfType, user_data);
  } else {
    return ReadValue(user_data);
  }
}

CFTypeRef FlutterStandardCodecHelperReadValueOfType(
    unsigned long* location,
    CFDataRef data,
    uint8_t type,
    CFTypeRef (*ReadValue)(CFTypeRef),
    CFTypeRef (*ReadTypedDataOfType)(FlutterStandardField, CFTypeRef),
    CFTypeRef user_data) {
  FlutterStandardField field = (FlutterStandardField)type;
  switch (field) {
    case FlutterStandardFieldNil:
      return nil;
    case FlutterStandardFieldTrue:
      return kCFBooleanTrue;
    case FlutterStandardFieldFalse:
      return kCFBooleanFalse;
    case FlutterStandardFieldInt32: {
      int32_t value;
      FlutterStandardCodecHelperReadBytes(location, 4, &value, data);
      return CFAutorelease(
          CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value));
    }
    case FlutterStandardFieldInt64: {
      int64_t value;
      FlutterStandardCodecHelperReadBytes(location, 8, &value, data);
      return CFAutorelease(
          CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
    }
    case FlutterStandardFieldFloat64: {
      Float64 value;
      FlutterStandardCodecHelperReadAlignment(location, 8);
      FlutterStandardCodecHelperReadBytes(location, 8, &value, data);
      return CFAutorelease(
          CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
    }
    case FlutterStandardFieldIntHex:
    case FlutterStandardFieldString:
      return FlutterStandardCodecHelperReadUTF8(location, data);
    case FlutterStandardFieldUInt8Data:
    case FlutterStandardFieldInt32Data:
    case FlutterStandardFieldInt64Data:
    case FlutterStandardFieldFloat32Data:
    case FlutterStandardFieldFloat64Data:
      return ReadTypedDataOfType(field, user_data);
    case FlutterStandardFieldList: {
      UInt32 length = FlutterStandardCodecHelperReadSize(location, data);
      CFMutableArrayRef array = CFArrayCreateMutable(
          kCFAllocatorDefault, length, &kCFTypeArrayCallBacks);
      for (UInt32 i = 0; i < length; i++) {
        CFTypeRef value = FastReadValue(location, data, ReadValue,
                                        ReadTypedDataOfType, user_data);
        CFArrayAppendValue(array, (value == nil ? kCFNull : value));
      }
      return CFAutorelease(array);
    }
    case FlutterStandardFieldMap: {
      UInt32 size = FlutterStandardCodecHelperReadSize(location, data);
      CFMutableDictionaryRef dict = CFDictionaryCreateMutable(
          kCFAllocatorDefault, size, &kCFTypeDictionaryKeyCallBacks,
          &kCFTypeDictionaryValueCallBacks);
      for (UInt32 i = 0; i < size; i++) {
        CFTypeRef key = FastReadValue(location, data, ReadValue,
                                      ReadTypedDataOfType, user_data);
        CFTypeRef val = FastReadValue(location, data, ReadValue,
                                      ReadTypedDataOfType, user_data);
        CFDictionaryAddValue(dict, (key == nil ? kCFNull : key),
                             (val == nil ? kCFNull : val));
      }
      return CFAutorelease(dict);
    }
    default:
      // Malformed message.
      FML_DCHECK(false);
  }
}

void FlutterStandardCodecHelperWriteByte(CFMutableDataRef data, uint8_t value) {
  CFDataAppendBytes(data, &value, 1);
}

void FlutterStandardCodecHelperWriteBytes(CFMutableDataRef data,
                                          const void* bytes,
                                          unsigned long length) {
  CFDataAppendBytes(data, static_cast<const UInt8*>(bytes), length);
}

void FlutterStandardCodecHelperWriteSize(CFMutableDataRef data, uint32_t size) {
  if (size < 254) {
    FlutterStandardCodecHelperWriteByte(data, size);
  } else if (size <= 0xffff) {
    FlutterStandardCodecHelperWriteByte(data, 254);
    UInt16 value = (UInt16)size;
    FlutterStandardCodecHelperWriteBytes(data, &value, 2);
  } else {
    FlutterStandardCodecHelperWriteByte(data, 255);
    FlutterStandardCodecHelperWriteBytes(data, &size, 4);
  }
}

void FlutterStandardCodecHelperWriteAlignment(CFMutableDataRef data,
                                              uint8_t alignment) {
  uint8_t mod = CFDataGetLength(data) % alignment;
  if (mod) {
    for (int i = 0; i < (alignment - mod); i++) {
      FlutterStandardCodecHelperWriteByte(data, 0);
    }
  }
}

void FlutterStandardCodecHelperWriteUTF8(CFMutableDataRef data,
                                         CFStringRef value) {
  const char* utf8 = CFStringGetCStringPtr(value, kCFStringEncodingUTF8);
  if (utf8) {
    size_t length = strlen(utf8);
    FlutterStandardCodecHelperWriteSize(data, length);
    FlutterStandardCodecHelperWriteBytes(data, utf8, length);
  } else {
    CFIndex length = CFStringGetLength(value);
    CFIndex used_length = 0;
    // UTF16 length times 3 will fit all UTF8.
    CFIndex buffer_length = length * 3;
    std::vector<UInt8> buffer;
    buffer.reserve(buffer_length);
    CFStringGetBytes(value, CFRangeMake(0, length), kCFStringEncodingUTF8, 0,
                     false, buffer.data(), buffer_length, &used_length);
    FlutterStandardCodecHelperWriteSize(data, used_length);
    FlutterStandardCodecHelperWriteBytes(data, buffer.data(), used_length);
  }
}

void FlutterStandardCodecHelperWriteData(CFMutableDataRef data,
                                         CFDataRef value) {
  const UInt8* bytes = CFDataGetBytePtr(value);
  CFIndex length = CFDataGetLength(value);
  FlutterStandardCodecHelperWriteBytes(data, bytes, length);
}

bool FlutterStandardCodecHelperWriteNumber(CFMutableDataRef data,
                                           CFNumberRef number) {
  bool success = false;
  if (CFGetTypeID(number) == CFBooleanGetTypeID()) {
    bool b = CFBooleanGetValue((CFBooleanRef)number);
    FlutterStandardCodecHelperWriteByte(
        data, (b ? FlutterStandardFieldTrue : FlutterStandardFieldFalse));
    success = true;
  } else if (CFNumberIsFloatType(number)) {
    Float64 f;
    success = CFNumberGetValue(number, kCFNumberFloat64Type, &f);
    if (success) {
      FlutterStandardCodecHelperWriteByte(data, FlutterStandardFieldFloat64);
      FlutterStandardCodecHelperWriteAlignment(data, 8);
      FlutterStandardCodecHelperWriteBytes(data, &f, 8);
    }
  } else if (CFNumberGetByteSize(number) <= 4) {
    SInt32 n;
    success = CFNumberGetValue(number, kCFNumberSInt32Type, &n);
    if (success) {
      FlutterStandardCodecHelperWriteByte(data, FlutterStandardFieldInt32);
      FlutterStandardCodecHelperWriteBytes(data, &n, 4);
    }
  } else if (CFNumberGetByteSize(number) <= 8) {
    SInt64 n;
    success = CFNumberGetValue(number, kCFNumberSInt64Type, &n);
    if (success) {
      FlutterStandardCodecHelperWriteByte(data, FlutterStandardFieldInt64);
      FlutterStandardCodecHelperWriteBytes(data, &n, 8);
    }
  }
  return success;
}

// NOLINTEND(google-runtime-int)
