//
// Copyright 2018 Google LLC.
//
// 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 <XCTest/XCTest.h>

#import "Service/Sources/EDOExecutor.h"
#import "Service/Sources/EDOServiceError.h"

@interface EDOExecutorTest : XCTestCase

@property(readonly) void (^emptyBlock)(void);

@end

@implementation EDOExecutorTest

- (void)testExecutorNotRunningToHandleMessageWithoutQueue {
  EDOExecutor *executor = [[EDOExecutor alloc] initWithQueue:nil];

  NSError *error;
  XCTAssertFalse([executor handleBlock:self.emptyBlock error:&error]);
  XCTAssertEqualObjects(error.domain, EDOServiceErrorDomain);
  XCTAssertEqual(error.code, EDOServiceErrorRequestNotHandled);
  XCTAssertTrue([error.userInfo.description containsString:@"execution queue is already released"]);
}

- (void)testExecutorNotRunningToHandleMessageWithQueue {
  dispatch_queue_t queue = [self testQueue];
  EDOExecutor *executor = [[EDOExecutor alloc] initWithQueue:queue];
  __block BOOL executed = NO;
  [executor
      handleBlock:^{
        executed = YES;
      }
            error:nil];
  XCTAssertTrue(executed);
}

- (void)testExecutorFinishRunningAfterClosingMessageQueue {
  dispatch_queue_t queue = [self testQueue];
  EDOExecutor *executor = [[EDOExecutor alloc] initWithQueue:queue];

  XCTestExpectation *expectFinish = [self expectationWithDescription:@"The executor is finished."];
  dispatch_async(queue, ^{
    [executor loopWithBlock:self.emptyBlock];
    // Only fulfills the exepectation after the executor finishes the run.
    [expectFinish fulfill];
  });

  [self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)testExecutorHandleMessageAfterClosingQueue {
  dispatch_queue_t queue = [self testQueue];
  EDOExecutor *executor = [[EDOExecutor alloc] initWithQueue:queue];

  XCTestExpectation *expectClose = [self expectationWithDescription:@"The queue is closed."];
  dispatch_async(queue, ^{
    [executor loopWithBlock:^{
      [expectClose fulfill];
    }];
  });

  [self waitForExpectationsWithTimeout:1 handler:nil];
  [executor handleBlock:self.emptyBlock error:nil];
}

- (void)testSendRequestWithExecutorProcessingStressfully {
  NS_VALID_UNTIL_END_OF_SCOPE dispatch_queue_t queue = [self testQueue];
  EDOExecutor *executor = [[EDOExecutor alloc] initWithQueue:queue];

  XCTestExpectation *expectFinish = [self expectationWithDescription:@"The executor is finished."];
  expectFinish.expectedFulfillmentCount = 3;
  NSInteger numRuns = 1000;
  __block NSInteger numLoops = 0;
  dispatch_async(queue, ^{
    for (NSInteger i = 0; i < numRuns; ++i) {
      [executor loopWithBlock:^{
        ++numLoops;
      }];
    }
    [expectFinish fulfill];
  });

  // Generate requests from differnt QoS queues so it can cover cases:
  // 1. the request is received before the executor starts
  // 2. the request is received after the executor starts but before the while-loop starts
  // 3. the request is received after the while-loop tarts.
  __block NSInteger numHandlesHighPriority = 0;
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    for (NSInteger i = 0; i < numRuns; ++i) {
      [executor
          handleBlock:^{
            ++numHandlesHighPriority;
          }
                error:nil];
    }
    [expectFinish fulfill];
  });
  __block NSInteger numHandlesLowPriority = 0;
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    for (NSInteger i = 0; i < numRuns; ++i) {
      [executor
          handleBlock:^{
            ++numHandlesLowPriority;
          }
                error:nil];
    }
    [expectFinish fulfill];
  });
  [self waitForExpectationsWithTimeout:0.1 * numRuns handler:nil];
  XCTAssertEqual(numLoops, numRuns);
  XCTAssertEqual(numHandlesHighPriority, numRuns);
  XCTAssertEqual(numHandlesLowPriority, numRuns);
}

- (void)testSendRequestWithNestedExecutorProcessingStressfully {
  NS_VALID_UNTIL_END_OF_SCOPE dispatch_queue_t queue = [self testQueue];
  XCTestExpectation *expectFinish = [self expectationWithDescription:@"The executor is finished."];
  const NSInteger numThreadsHighQos = 6;
  const NSInteger numThreadsLowQos = 3;
  const NSInteger numRuns = 100;
  expectFinish.expectedFulfillmentCount = numThreadsHighQos + numThreadsLowQos;

  EDOExecutor *executor = [[EDOExecutor alloc] initWithQueue:queue];
  void (^handlerBlock)(void) = ^{
    [executor loopWithBlock:^{
    }];
  };

  dispatch_async(queue, ^{
    [executor loopWithBlock:^{
      dispatch_group_t requestsGroup = dispatch_group_create();
      for (NSInteger i = 0; i < numThreadsHighQos; ++i) {
        dispatch_group_enter(requestsGroup);
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
          for (NSInteger j = 0; j < numRuns; ++j) {
            [executor handleBlock:handlerBlock error:nil];
          }
          dispatch_group_leave(requestsGroup);
          [expectFinish fulfill];
        });
      }
      for (NSInteger i = 0; i < numThreadsLowQos; ++i) {
        dispatch_group_enter(requestsGroup);
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
          for (NSInteger j = 0; j < numRuns; ++j) {
            [executor handleBlock:handlerBlock error:nil];
          }
          dispatch_group_leave(requestsGroup);
          [expectFinish fulfill];
        });
      }
      dispatch_group_wait(requestsGroup, DISPATCH_TIME_FOREVER);
    }];
  });
  [self waitForExpectationsWithTimeout:0.1 * numRuns * (numThreadsHighQos + numThreadsLowQos)
                               handler:nil];
}

#pragma mark - Test helper methods

- (void (^)(void))emptyBlock {
  return ^{
  };
}

/** Create a dispatch queue with the current testname. */
- (dispatch_queue_t)testQueue {
  NSString *queueName = [NSString stringWithFormat:@"com.google.edo.Executor[%@]", self.name];
  return dispatch_queue_create(queueName.UTF8String, DISPATCH_QUEUE_SERIAL);
}

@end
