//
// Copyright 2018 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/NSKeyedArchiver+EDOAdditions.h"

#import <objc/runtime.h>

#import "Service/Sources/EDOClientService.h"
#import "Service/Sources/EDOServiceError.h"
#import "Service/Sources/EDOServiceException.h"

NS_ASSUME_NONNULL_BEGIN

/** The delegate used for encoding eDO outgoing parameters. */
@interface EDOKeyedArchiverDelegate : NSObject <NSKeyedArchiverDelegate>

/** Initializes the object with the root object that is going to be encoded. */
- (instancetype)initWithRootObject:(id)rootObject NS_DESIGNATED_INITIALIZER;

- (instancetype)init NS_UNAVAILABLE;

@end

@implementation EDOKeyedArchiverDelegate {
  /** The object that is encoded by the attached NSKeyedArchiver of this delegate. */
  id _rootObject;
}

- (instancetype)initWithRootObject:(id)rootObject {
  self = [super init];
  if (self) {
    _rootObject = rootObject;
  }
  return self;
}

#pragma mark - NSKeyedArchiverDelegate

- (nullable id)archiver:(NSKeyedArchiver *)archiver willEncodeObject:(id)object {
  if (!EDOIsRemoteObject(object) &&
      [object respondsToSelector:@selector(EDOCheckEncodingConformance:)]) {
    NSError *error;
    if (![object EDOCheckEncodingConformance:&error]) {
      [self raiseEncodingConformanceError:error withEncodingObject:object];
    }
  }
  return object;
}

#pragma mark - Private

/**
 * Throws an exception for the failed NSCoding conformance check during the encoding procedure.
 *
 * @param error  The error that contains the underlying reason that encoding will fail. The error
 *               reason must be included in the `EDOErrorEncodingFailureReasonKey` of the
 *               `userInfo`.
 * @param object The object that will cause the encoding failure.
 */
- (void)raiseEncodingConformanceError:(NSError *)error withEncodingObject:(id)object {
  NSString *reason = [NSString
      stringWithFormat:
          @"eDO fails to encode a parameter which is sent for remote invocation. Please check if "
          @"the parameter fully conforming to NSCoding.\n\nThe parameter is: %@\nDetail: %@",
          [_rootObject description], error.userInfo[EDOErrorEncodingFailureReasonKey]];
  [[NSException exceptionWithName:EDOTypeEncodingException reason:reason userInfo:nil] raise];
}

/** @return Awalys @c NO because this class doesn't conform to NSCoding. */
- (BOOL)EDOCheckEncodingConformance:(NSError **)error {
  return NO;
}

@end

@implementation NSKeyedArchiver (EDOAdditions)

+ (NSData *)edo_archivedDataWithObject:(id)object {
  // In Xcode 10.0, we can use the newer APIs.
#if (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101400) || \
    (defined(__TV_OS_VERSION_MAX_ALLOWED) && __TV_OS_VERSION_MAX_ALLOWED >= 120000) ||       \
    (defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED >= 120000) || \
    (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000)
  if (@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *)) {
    // Use instancesRespondToSelector check because it's possible that something loads this on a
    // lower iOS version than what it was built with, in which case the availability macros alone
    // fail to protect it.
    if ([NSKeyedArchiver instancesRespondToSelector:@selector(initRequiringSecureCoding:)]) {
      NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:NO];
      EDOKeyedArchiverDelegate *delegate =
          [[EDOKeyedArchiverDelegate alloc] initWithRootObject:object];
      archiver.delegate = delegate;
      [archiver encodeObject:object forKey:NSKeyedArchiveRootObjectKey];
      [archiver finishEncoding];
      return archiver.encodedData;
    }
  }
#endif

  return [NSKeyedArchiver archivedDataWithRootObject:object requiringSecureCoding:NO error:nil];
}

@end

NS_ASSUME_NONNULL_END
