/*
 *
 * Copyright 2019 gRPC authors.
 *
 * 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 "PerfTests.h"

#include <grpc/status.h>

#import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+Cronet.h>
#import <GRPCClient/GRPCCall+Interceptor.h>
#import <GRPCClient/GRPCCall+Tests.h>
#import <GRPCClient/GRPCInterceptor.h>
#import <GRPCClient/internal_testing/GRPCCall+InternalTests.h>
#import <ProtoRPC/ProtoRPC.h>
#import <RxLibrary/GRXBufferedPipe.h>
#import <RxLibrary/GRXWriter+Immediate.h>
#import <grpc/grpc.h>
#import <grpc/support/log.h>
#import "src/objective-c/tests/RemoteTestClient/Messages.pbobjc.h"
#import "src/objective-c/tests/RemoteTestClient/Test.pbobjc.h"
#import "src/objective-c/tests/RemoteTestClient/Test.pbrpc.h"

#import "PerfTestsBlockCallbacks.h"

#define TEST_TIMEOUT 128

extern const char *kCFStreamVarName;

// Convenience constructors for the generated proto messages:

@interface RMTStreamingOutputCallRequest (Constructors)
+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize
                 requestedResponseSize:(NSNumber *)responseSize;
@end

@implementation RMTStreamingOutputCallRequest (Constructors)
+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize
                 requestedResponseSize:(NSNumber *)responseSize {
  RMTStreamingOutputCallRequest *request = [self message];
  RMTResponseParameters *parameters = [RMTResponseParameters message];
  parameters.size = responseSize.intValue;
  [request.responseParametersArray addObject:parameters];
  request.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue];
  return request;
}
@end

@interface DefaultInterceptorFactory : NSObject <GRPCInterceptorFactory>

- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager;

@end

@implementation DefaultInterceptorFactory

- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager {
  dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
  return [[GRPCInterceptor alloc] initWithInterceptorManager:interceptorManager
                                               dispatchQueue:queue];
}

@end

#pragma mark Tests

@implementation PerfTests {
  RMTTestService *_service;
}

+ (XCTestSuite *)defaultTestSuite {
  if (self == [PerfTests class]) {
    return [XCTestSuite testSuiteWithName:@"PerfTestsEmptySuite"];
  } else {
    return super.defaultTestSuite;
  }
}

+ (NSString *)host {
  return nil;
}

// This number indicates how many bytes of overhead does Protocol Buffers encoding add onto the
// message. The number varies as different message.proto is used on different servers. The actual
// number for each interop server is overridden in corresponding derived test classes.
- (int32_t)encodingOverhead {
  return 0;
}

+ (GRPCTransportID)transport {
  return NULL;
}

+ (NSString *)PEMRootCertificates {
  return nil;
}

+ (NSString *)hostNameOverride {
  return nil;
}

- (void)setUp {
  self.continueAfterFailure = NO;

  [GRPCCall resetHostSettings];

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
  [GRPCCall closeOpenConnections];
#pragma clang diagnostic pop

  _service = [[self class] host] ? [RMTTestService serviceWithHost:[[self class] host]] : nil;
}

- (BOOL)isUsingCFStream {
  return [NSStringFromClass([self class]) isEqualToString:@"PerfTestsCFStreamSSL"];
}

- (void)pingPongV2APIWithRequest:(RMTStreamingOutputCallRequest *)request
                     numMessages:(int)numMessages
                         options:(GRPCMutableCallOptions *)options {
  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];

  __block BOOL flowControlEnabled = options.flowControlEnabled;
  __block int index = 0;
  __block GRPCStreamingProtoCall *call = [self->_service
      fullDuplexCallWithResponseHandler:[[PerfTestsBlockCallbacks alloc]
                                            initWithInitialMetadataCallback:nil
                                            messageCallback:^(id message) {
                                              int indexCopy;
                                              @synchronized(self) {
                                                indexCopy = index;
                                                index += 1;
                                              }
                                              if (indexCopy < numMessages) {
                                                [call writeMessage:request];
                                                if (flowControlEnabled) {
                                                  [call receiveNextMessage];
                                                }
                                              } else {
                                                [call finish];
                                              }
                                            }
                                            closeCallback:^(NSDictionary *trailingMetadata,
                                                            NSError *error) {
                                              [expectation fulfill];
                                            }]
                            callOptions:options];
  [call start];
  if (flowControlEnabled) {
    [call receiveNextMessage];
  }
  [call writeMessage:request];
  [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}

- (void)testPingPongRPCWithV2API {
  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
  options.transport = [[self class] transport];
  options.PEMRootCertificates = [[self class] PEMRootCertificates];
  options.hostNameOverride = [[self class] hostNameOverride];

  id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];

  // warm up
  [self pingPongV2APIWithRequest:request numMessages:1000 options:options];

  [self measureBlock:^{
    [self pingPongV2APIWithRequest:request numMessages:1000 options:options];
  }];
}

- (void)testPingPongRPCWithFlowControl {
  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
  options.transport = [[self class] transport];
  options.PEMRootCertificates = [[self class] PEMRootCertificates];
  options.hostNameOverride = [[self class] hostNameOverride];
  options.flowControlEnabled = YES;

  id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];

  // warm up
  [self pingPongV2APIWithRequest:request numMessages:1000 options:options];

  [self measureBlock:^{
    [self pingPongV2APIWithRequest:request numMessages:1000 options:options];
  }];
}

- (void)testPingPongRPCWithInterceptor {
  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
  options.transport = [[self class] transport];
  options.PEMRootCertificates = [[self class] PEMRootCertificates];
  options.hostNameOverride = [[self class] hostNameOverride];
  options.interceptorFactories = @[ [[DefaultInterceptorFactory alloc] init] ];

  id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];

  // warm up
  [self pingPongV2APIWithRequest:request numMessages:1000 options:options];

  [self measureBlock:^{
    [self pingPongV2APIWithRequest:request numMessages:1000 options:options];
  }];
}

- (void)pingPongV1APIWithRequest:(RMTStreamingOutputCallRequest *)request
                     numMessages:(int)numMessages {
  __block int index = 0;
  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"];
  GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];

  [requestsBuffer writeValue:request];

  [_service fullDuplexCallWithRequestsWriter:requestsBuffer
                                eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response,
                                               NSError *error) {
                                  if (response) {
                                    int indexCopy;
                                    @synchronized(self) {
                                      index += 1;
                                      indexCopy = index;
                                    }
                                    if (indexCopy < numMessages) {
                                      [requestsBuffer writeValue:request];
                                    } else {
                                      [requestsBuffer writesFinishedWithError:nil];
                                    }
                                  }

                                  if (done) {
                                    [expectation fulfill];
                                  }
                                }];
  [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}

- (void)testPingPongRPCWithV1API {
  id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:@1 requestedResponseSize:@1];
  [self pingPongV1APIWithRequest:request numMessages:1000];
  [self measureBlock:^{
    [self pingPongV1APIWithRequest:request numMessages:1000];
  }];
}

- (void)unaryRPCsWithServices:(NSArray<RMTTestService *> *)services
                      request:(RMTSimpleRequest *)request
              callsPerService:(int)callsPerService
          maxOutstandingCalls:(int)maxOutstandingCalls
                  callOptions:(GRPCMutableCallOptions *)options {
  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"unaryRPC"];

  dispatch_semaphore_t sema = dispatch_semaphore_create(maxOutstandingCalls);
  __block int index = 0;

  for (RMTTestService *service in services) {
    for (int i = 0; i < callsPerService; ++i) {
      GRPCUnaryProtoCall *call = [service
          unaryCallWithMessage:request
               responseHandler:[[PerfTestsBlockCallbacks alloc]
                                   initWithInitialMetadataCallback:nil
                                                   messageCallback:nil
                                                     closeCallback:^(NSDictionary *trailingMetadata,
                                                                     NSError *error) {
                                                       dispatch_semaphore_signal(sema);
                                                       @synchronized(self) {
                                                         ++index;
                                                         if (index ==
                                                             callsPerService * [services count]) {
                                                           [expectation fulfill];
                                                         }
                                                       }
                                                     }]
                   callOptions:options];
      dispatch_time_t timeout =
          dispatch_time(DISPATCH_TIME_NOW, (int64_t)(TEST_TIMEOUT * NSEC_PER_SEC));
      dispatch_semaphore_wait(sema, timeout);
      [call start];
    }
  }

  [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}

- (void)test1MBUnaryRPC {
  // Workaround Apple CFStream bug
  if ([self isUsingCFStream]) {
    return;
  }

  RMTSimpleRequest *request = [RMTSimpleRequest message];
  request.responseSize = 1048576;
  request.payload.body = [NSMutableData dataWithLength:1048576];

  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
  options.transport = [[self class] transport];
  options.PEMRootCertificates = [[self class] PEMRootCertificates];
  options.hostNameOverride = [[self class] hostNameOverride];

  // warm up
  [self unaryRPCsWithServices:@[ self->_service ]
                      request:request
              callsPerService:50
          maxOutstandingCalls:10
                  callOptions:options];

  [self measureBlock:^{
    [self unaryRPCsWithServices:@[ self->_service ]
                        request:request
                callsPerService:50
            maxOutstandingCalls:10
                    callOptions:options];
  }];
}

- (void)test1KBUnaryRPC {
  RMTSimpleRequest *request = [RMTSimpleRequest message];
  request.responseSize = 1024;
  request.payload.body = [NSMutableData dataWithLength:1024];

  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
  options.transport = [[self class] transport];
  options.PEMRootCertificates = [[self class] PEMRootCertificates];
  options.hostNameOverride = [[self class] hostNameOverride];

  // warm up
  [self unaryRPCsWithServices:@[ self->_service ]
                      request:request
              callsPerService:1000
          maxOutstandingCalls:100
                  callOptions:options];

  [self measureBlock:^{
    [self unaryRPCsWithServices:@[ self->_service ]
                        request:request
                callsPerService:1000
            maxOutstandingCalls:100
                    callOptions:options];
  }];
}

- (void)testMultipleChannels {
  NSString *port = [[[self class] host] componentsSeparatedByString:@":"][1];
  int kNumAddrs = 10;
  NSMutableArray<NSString *> *addrs = [NSMutableArray arrayWithCapacity:kNumAddrs];
  NSMutableArray<RMTTestService *> *services = [NSMutableArray arrayWithCapacity:kNumAddrs];
  for (int i = 0; i < kNumAddrs; ++i) {
    // http://readme.localtest.me/
    addrs[i] = [NSString stringWithFormat:@"%d.localtest.me", (i + 1)];
    NSString *hostWithPort = [NSString stringWithFormat:@"%@:%@", addrs[i], port];
    services[i] = [RMTTestService serviceWithHost:hostWithPort];
  }

  RMTSimpleRequest *request = [RMTSimpleRequest message];
  request.responseSize = 0;
  request.payload.body = [NSMutableData dataWithLength:0];

  GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init];
  options.transport = [[self class] transport];
  options.PEMRootCertificates = [[self class] PEMRootCertificates];
  options.hostNameOverride = [[self class] hostNameOverride];

  // warm up
  [self unaryRPCsWithServices:services
                      request:request
              callsPerService:100
          maxOutstandingCalls:100
                  callOptions:options];

  [self measureBlock:^{
    [self unaryRPCsWithServices:services
                        request:request
                callsPerService:100
            maxOutstandingCalls:100
                    callOptions:options];
  }];
}

@end
