//
// Copyright 2020 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#import "Service/Sources/EDOBlockObject.h"

#include <objc/message.h>
#include <objc/runtime.h>

#import "Service/Sources/EDOObject+Private.h"

@class EDOServicePort;

static NSString *const kEDOBlockObjectCoderSignatureKey = @"signature";
static NSString *const kEDOBlockObjectCoderHasStretKey = @"hasStret";

/**
 * The block structure defined in ABI here:
 * https://clang.llvm.org/docs/Block-ABI-Apple.html#id2
 */

struct EDOBlockHeader;

typedef void (*EDOBlockCopyHelperFunc)(struct EDOBlockHeader *dst, struct EDOBlockHeader *src);
typedef void (*EDOBlockDisposeHelperFunc)(struct EDOBlockHeader *src);

typedef struct EDOBlockDescriptor {
  unsigned long int reserved;
  unsigned long int size;
  union {
    struct {
      // Optional helper functions
      EDOBlockCopyHelperFunc copy_helper;        // IFF (flag & 1<<25)
      EDOBlockDisposeHelperFunc dispose_helper;  // IFF (flag & 1<<25)
      const char *signature;
    } helper;
    // Required ABI.2010.3.16
    const char *signature;  // IFF (flag & 1<<30)
  };
} EDOBlockDescriptor;

/** The enums for the block flag. */
typedef NS_ENUM(int, EDOBlockFlags) {
  EDOBlockFlagsHasCopyDispose = (1 << 25),  // If the block has copy and dispose function pointer.
  EDOBlockFlagsIsGlobal = (1 << 28),        // If the block is a global block.
  EDOBlockFlagsHasStret = (1 << 29),        // If we should use _stret calling convention.
  EDOBlockFlagsHasSignature = (1 << 30)     // If the signature is filled.
};

typedef struct {
  id __unsafe_unretained object;
  EDOBlockFlags original_flags;
  EDOBlockDescriptor *original_descriptor;
} EDOBlockCapturedVariables;

typedef struct EDOBlockHeader {
  void *isa;
  EDOBlockFlags flags;
  int reserved;
  void (*invoke)(void);  // The block implementation, which is either _objc_msgForward or
                         // _objc_msgForward_stret to trigger message forwarding.
  EDOBlockDescriptor *descriptor;
  EDOBlockCapturedVariables captured_variables;
} EDOBlockHeader;

typedef NS_ENUM(int, EDOBlockFieldDescriptors) {
  EDOBlockFieldIsObject = 3,  // id, NSObject, __attribute__((NSObject)), block, ...
};

/* Get @c NSBlock class. */
static Class GetBlockBaseClass() {
  static Class blockClass;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    blockClass = NSClassFromString(@"NSBlock");
    NSCAssert(blockClass, @"Couldn't load NSBlock class.");
  });
  return blockClass;
}

/** Check if the @c block has struct returns. */
static BOOL HasStructReturnForBlock(id block) {
  EDOBlockHeader *blockHeader = (__bridge EDOBlockHeader *)block;
  return (blockHeader->flags & EDOBlockFlagsHasStret) != 0;
}

@implementation EDOBlockObject

+ (BOOL)supportsSecureCoding {
  return YES;
}

+ (BOOL)isBlock:(id)object {
  if ([object isProxy]) {
    return NO;
  }

  // We use runtime primitive APIs to go through the class hierarchy in case any subclass to
  // override -[isKindOfClass:] and cause unintended behaviours, i.e. OCMock.
  Class blockClass = GetBlockBaseClass();
  Class objClass = object_getClass(object);
  while (objClass) {
    if (objClass == blockClass) {
      return YES;
    }
    objClass = class_getSuperclass(objClass);
  }
  return NO;
}

+ (EDOBlockObject *)EDOBlockObjectFromBlock:(id)block {
  EDOBlockHeader *header = (__bridge EDOBlockHeader *)block;
#if !defined(__arm64__)
  if (header->invoke == (void (*)(void))_objc_msgForward ||
      header->invoke == (void (*)(void))_objc_msgForward_stret) {
    return header->captured_variables.object;
  }
#else
  if (header->invoke == (void (*)(void))_objc_msgForward) {
    return header->captured_variables.object;
  }
#endif
  return nil;
}

+ (char const *)signatureFromBlock:(id)block {
  EDOBlockHeader *blockHeader = (__bridge EDOBlockHeader *)block;
  NSAssert(blockHeader->flags & EDOBlockFlagsHasSignature, @"The block doesn't have a signature.");
  if (blockHeader->flags & EDOBlockFlagsHasCopyDispose) {
    return blockHeader->descriptor->helper.signature;
  } else {
    return blockHeader->descriptor->signature;
  }
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
  self = [super initWithCoder:aDecoder];
  if (self) {
    _signature = [aDecoder decodeObjectOfClass:[NSString class]
                                        forKey:kEDOBlockObjectCoderSignatureKey];
    _returnsStruct = [aDecoder decodeBoolForKey:kEDOBlockObjectCoderHasStretKey];
  }
  return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
  [super encodeWithCoder:aCoder];
  [aCoder encodeObject:self.signature forKey:kEDOBlockObjectCoderSignatureKey];
  [aCoder encodeBool:self.returnsStruct forKey:kEDOBlockObjectCoderHasStretKey];
}

// Dispose the returned descriptor using DisposeDescriptor.
static EDOBlockDescriptor *CreateDescriptorWithSignature(NSString *signature) {
  EDOBlockDescriptor *newDescriptor = (EDOBlockDescriptor *)calloc(1, sizeof(EDOBlockDescriptor));
  // Note that we only do dispose because our block should never have a copy handler.
  newDescriptor->helper.dispose_helper = EDOBlockDisposeHelper;
  newDescriptor->helper.signature = strdup([signature UTF8String]);
  return newDescriptor;
}

static void DisposeDescriptor(EDOBlockDescriptor *desc) {
  // Free up the memory that we allocated for the signature and our descriptor.
  free((void *)desc->helper.signature);
  free((void *)desc);
}

static void EDOBlockDisposeHelper(EDOBlockHeader *src) {
  // Dispose is only called once when the block is being released.
  // Dispose/Release our captured object.
  _Block_object_dispose((__bridge void *)src->captured_variables.object, EDOBlockFieldIsObject);

  // Free up the memory that we allocated for the descriptor.
  DisposeDescriptor(src->descriptor);

  // Reset the header back the way it was.
  src->descriptor = src->captured_variables.original_descriptor;
  src->flags = src->captured_variables.original_flags;

  // We don't need to call the previous dispose helper because we asserted that there wasn't one
  // when we created the block.
}

// When we decode it, we swap with the actual block object so the receiver can invoke on it.
- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder {
  EDOBlockCapturedVariables vars = {nil, 0, NULL};
  void (^dummy)(void) = ^{
    // The printf is never called, it solely exists to capture vars to associate it with the block
    // so we get the proper amount of "variable" space in our block header.
    printf("%p", vars.original_descriptor);
  };

  // Move the block from the stack to the heap.
  id dummyOnHeap = [dummy copy];
  EDOBlockHeader *header = (__bridge EDOBlockHeader *)dummyOnHeap;

  // Verify that Apple hasn't added some fun optimizations that are copying our block in a
  // weird way.
  NSAssert(header->descriptor->size == sizeof(EDOBlockHeader), @"block wrong size");

  // Check to make sure that Apple hasn't added copy/dispose handlers to our blocks for some reason.
  // If they do, we will have to be careful to chain them in dispose.
  NSAssert((header->flags & EDOBlockFlagsHasCopyDispose) == 0, @"block has copy/dispose handlers");

  // Add a reference to "self" into the block.
  _Block_object_assign(&header->captured_variables.object, (__bridge void *)self,
                       EDOBlockFieldIsObject);

  // Record the original values from the header so we can restore them when we dispose the block.
  header->captured_variables.original_descriptor = header->descriptor;
  header->captured_variables.original_flags = header->flags;

  // Create up a new descriptor with our dispose and signature.
  // Note that we need to make a new descriptor because multiple blocks may be using the same
  // descriptor that the compiler generates for us, and modifying it directly can mess up other
  // blocks. We create our own, and then clean up all the memory in EDOBlockDisposeHelper.
  EDOBlockDescriptor *newDescriptor = CreateDescriptorWithSignature(self.signature);
  header->descriptor = newDescriptor;

  // Add the copy/dispose/signatures flags so that the OS calls us appropriately.
  header->flags |= (EDOBlockFlagsHasCopyDispose | EDOBlockFlagsHasSignature);

  header->invoke = (void (*)(void))_objc_msgForward;
#if !defined(__arm64__)
  if (self.returnsStruct) {
    header->invoke = (void (*)(void))_objc_msgForward_stret;
  }
#endif

  // Swap the ownership: the unarchiver retains `self` and autoreleases the `dummyOnHeap` block.
  // Here we capture self within the `dummyOnHeap` block, and replace `self` with the `dummyOnHeap`
  // block. This effectively transfers the ownership of dummyOnHeap to the caller of the unarchiver.
  CFBridgingRelease((__bridge void *)self);
  return (__bridge id)CFBridgingRetain(dummyOnHeap);
}

- (instancetype)edo_initWithLocalObject:(id)target port:(EDOServicePort *)port {
  // object is self. This does the same as self = [super initWithLocalObject:target port:port], but
  // because we have the prefix to avoid the naming collisions, the compiler complains assigning
  // self in a non-init method.
  EDOBlockObject *object = [super edo_initWithLocalObject:target port:port];

  _returnsStruct = HasStructReturnForBlock(target);
  _signature = [NSString stringWithUTF8String:[EDOBlockObject signatureFromBlock:target]];
  return object;
}

@end
