/*
 *
 * Copyright 2015, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <grpc/status.h>

#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>

#import <gRPC/ProtoRPC.h>
#import <gRPC/GRXWriter+Immediate.h>
#import <RemoteTest/Empty.pbobjc.h>
#import <RemoteTest/Messages.pbobjc.h>
#import <RemoteTest/Test.pbobjc.h>
#import <RemoteTest/Test.pbrpc.h>

@interface RemoteProtoTests : XCTestCase
@end

@implementation RemoteProtoTests {
  RMTTestService *_service;
}

- (void)setUp {
  _service = [[RMTTestService alloc] initWithHost:@"grpc-test.sandbox.google.com"];
}

// Tests as described here: https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md

- (void)testEmptyUnaryRPC {
  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnary"];

  RMTEmpty *request = [RMTEmpty message];

  [_service emptyCallWithRequest:request handler:^(RMTEmpty *response, NSError *error) {
    XCTAssertNil(error, @"Finished with unexpected error: %@", error);

    id expectedResponse = [RMTEmpty message];
    XCTAssertEqualObjects(response, expectedResponse);

    [expectation fulfill];
  }];

  [self waitForExpectationsWithTimeout:2. handler:nil];
}

- (void)testLargeUnaryRPC {
  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"];

  RMTSimpleRequest *request = [RMTSimpleRequest message];
  request.responseType = RMTPayloadType_Compressable;
  request.responseSize = 314159;
  request.payload.body = [NSMutableData dataWithLength:271828];

  [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) {
    XCTAssertNil(error, @"Finished with unexpected error: %@", error);

    RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message];
    expectedResponse.payload.type = RMTPayloadType_Compressable;
    expectedResponse.payload.body = [NSMutableData dataWithLength:314159];
    XCTAssertEqualObjects(response, expectedResponse);

    [expectation fulfill];
  }];

  [self waitForExpectationsWithTimeout:4. handler:nil];
}

- (void)testClientStreamingRPC {
  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ClientStreaming"];

  RMTStreamingInputCallRequest *request1 = [RMTStreamingInputCallRequest message];
  request1.payload.body = [NSMutableData dataWithLength:27182];

  RMTStreamingInputCallRequest *request2 = [RMTStreamingInputCallRequest message];
  request2.payload.body = [NSMutableData dataWithLength:8];

  RMTStreamingInputCallRequest *request3 = [RMTStreamingInputCallRequest message];
  request3.payload.body = [NSMutableData dataWithLength:1828];

  RMTStreamingInputCallRequest *request4 = [RMTStreamingInputCallRequest message];
  request4.payload.body = [NSMutableData dataWithLength:45904];

  id<GRXWriter> writer = [GRXWriter writerWithContainer:@[request1, request2, request3, request4]];

  [_service streamingInputCallWithRequestsWriter:writer
                                         handler:^(RMTStreamingInputCallResponse *response,
                                                   NSError *error) {
    XCTAssertNil(error, @"Finished with unexpected error: %@", error);

    RMTStreamingInputCallResponse *expectedResponse = [RMTStreamingInputCallResponse message];
    expectedResponse.aggregatedPayloadSize = 74922;
    XCTAssertEqualObjects(response, expectedResponse);

    [expectation fulfill];
  }];

  [self waitForExpectationsWithTimeout:4. handler:nil];
}

- (void)testServerStreamingRPC {
  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ServerStreaming"];

  NSArray *expectedSizes = @[@31415, @9, @2653, @58979];

  RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
  for (NSNumber *size in expectedSizes) {
    RMTResponseParameters *parameters = [RMTResponseParameters message];
    parameters.size = [size integerValue];
    [request.responseParametersArray addObject:parameters];
  }

  __block int index = 0;
  [_service streamingOutputCallWithRequest:request
                                   handler:^(BOOL done,
                                             RMTStreamingOutputCallResponse *response,
                                             NSError *error){
    XCTAssertNil(error, @"Finished with unexpected error: %@", error);
    XCTAssertTrue(done || response, @"Event handler called without an event.");

    if (response) {
      XCTAssertLessThan(index, 4, @"More than 4 responses received.");
      RMTStreamingOutputCallResponse * expected = [RMTStreamingOutputCallResponse message];
      expected.payload.type = RMTPayloadType_Compressable;
      int expectedSize = [expectedSizes[index] unsignedIntegerValue];
      expected.payload.body = [NSMutableData dataWithLength:expectedSize];
      XCTAssertEqualObjects(response, expected);
      index += 1;
    }

    if (done) {
      XCTAssertEqual(index, 4, @"Received %i responses instead of 4.", index);
      [expectation fulfill];
    }
  }];
  
  [self waitForExpectationsWithTimeout:4 handler:nil];
}

- (void)testEmptyStreamRPC {
  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"];
  [_service fullDuplexCallWithRequestsWriter:[GRXWriter emptyWriter]
                                     handler:^(BOOL done,
                                               RMTStreamingOutputCallResponse *response,
                                               NSError *error) {
    XCTAssertNil(error, @"Finished with unexpected error: %@", error);
    XCTAssert(done, @"Unexpected response: %@", response);
    [expectation fulfill];
  }];
  [self waitForExpectationsWithTimeout:4 handler:nil];
}

- (void)testCancelAfterBeginRPC {
  __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBegin"];
  // TODO(mlumish): change to writing that blocks instead of writing
  ProtoRPC *call = [_service RPCToStreamingInputCallWithRequestsWriter:[GRXWriter emptyWriter]
                                                               handler:^(RMTStreamingInputCallResponse *response,
                                                                         NSError *error) {
    XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
    [expectation fulfill];
  }];
  [call start];
  [call cancel];
  [self waitForExpectationsWithTimeout:1 handler:nil];
}

@end
