//
//  CRSessionControllerTests.m
//  Courier
//
//  Created by Andrew Smith on 1/13/14.
//  Copyright (c) 2014 Andrew B. Smith ( http://github.com/drewsmits ). All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//

#import "CRTestCase.h"

#import "CRSessionController.h"
#import "CRAsyncTestHelpers.h"

#import <OHHTTPStubs/OHHTTPStubs.h>

#define kTestGroupName @"kBurritoCrew"
#define kTestGroup2Name @"kTacoCrew"

#define kTestTaskToken @"aToken"
#define kTestTask2Token @"bToken"

@interface CRSessionController (UnitTests)

@property (nonatomic, readonly) NSMutableDictionary *groups;

@property (nonatomic, readonly) NSMutableDictionary *tasksByToken;

@property (nonatomic, readonly) NSMutableDictionary *tasksByIdentifier;

@property (nonatomic, readonly) NSOperationQueue *serialQueue;

- (void)addTask:(NSURLSessionTask *)task
      withToken:(NSString *)token
        toGroup:(NSString *)group;

- (void)removeTaskWithToken:(NSString *)token;

- (void)logResponse:(NSURLResponse *)response
               data:(NSData *)data
              error:(NSError *)error;

@end

@interface CRSessionControllerTests : CRTestCase

@property (nonatomic, strong) CRSessionController *sessionController;

@end

@implementation CRSessionControllerTests

- (void)setUp
{
    [super setUp];

    _sessionController = [CRSessionController sessionControllerWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
    
    [OHHTTPStubs removeAllStubs];
    
    [[NSURLSessionConfiguration ephemeralSessionConfiguration].URLCache removeAllCachedResponses];
}

- (void)tearDown
{
    [OHHTTPStubs removeAllStubs];
    [super tearDown];
}

- (NSURLSessionTask *)googleTask
{
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];
    NSURLSessionTask *task = [_sessionController dataTaskForRequest:request completionHandler:nil];
    return task;
}

#pragma mark - Config

- (void)testSessionConfig
{
    XCTAssertNotNil(_sessionController.configuration,
                    @"Should have a non nil configuration");
}

#pragma mark -

- (void)testDataTaskForGroup
{
    [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
        return YES;
    } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) {
        return [OHHTTPStubsResponse responseWithData:[@"dummyData" dataUsingEncoding:NSUTF8StringEncoding]
                                          statusCode:301
                                             headers:@{@"Location" : @"http://www.nest.com"}];
    }];
    
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];

    XCTestExpectation *expectation = [self expectationWithDescription:@"task finished"];
    NSURLSessionDataTask *task = [_sessionController dataTaskForRequest:request
                                                              taskGroup:kTestGroupName
                                                      completionHandler:^(NSData *data,
                                                                          NSURLResponse *response,
                                                                          BOOL cachedResponse,
                                                                          NSError *error) {
                                                          [expectation fulfill];
                                                    }];
    
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];
    
    // check group
    NSArray *tasks = [_sessionController.groups valueForKey:kTestGroupName];
    XCTAssertEqualObjects([tasks firstObject],
                          task,
                          @"Should be the same task");
    
    // Check tasks
    XCTAssertEqual(_sessionController.tasksByToken.count,
                   1U,
                   @"Should have one task");
    
    id key = [[_sessionController.tasksByToken allKeys] firstObject];
    NSDictionary *object = [_sessionController.tasksByToken objectForKey:key];
    XCTAssertEqualObjects(object[@"group"],
                          kTestGroupName,
                          @"Should have correc group name");
    XCTAssertEqualObjects(object[@"task"],
                          task,
                          @"Should be the same task");
    
    [task resume];
    
    //
    // Wait until finished
    //
    [self waitForExpectationsWithTimeout:1.0 handler:nil];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];
    
    XCTAssertEqual(_sessionController.groups.count,
                   0U,
                   @"Should have no task groups after completion");
    
    XCTAssertEqual(_sessionController.tasksByToken.count,
                   0U,
                   @"Should have no tasks after completion");
    
    XCTAssertEqual(_sessionController.tasksByIdentifier.count,
                   0U,
                   @"Should have no tasks after completion");
}

#pragma mark - Task Management

- (void)testAddTask
{
    NSArray *tasks = [_sessionController.groups valueForKey:kTestGroupName];
    XCTAssertNil(tasks, @"Should not have a task array for group");
    
    NSURLSessionTask *task = [NSURLSessionTask new];
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:kTestGroupName];
    
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];
    
    tasks = [_sessionController.groups valueForKey:kTestGroupName];
    
    XCTAssertNotNil(tasks, @"Should have a task array for group");
    XCTAssertEqual(tasks.count, 1U, @"Should have one task for group");
    XCTAssertEqualObjects([tasks firstObject], task, @"Should be the same task");
    
    XCTAssertNotNil(_sessionController.tasksByToken, @"Should have a tasks by token dictionary");
    XCTAssertEqual(_sessionController.tasksByToken.count, 1U, @"Should have one task for group");

    XCTAssertNotNil(_sessionController.tasksByIdentifier, @"Should have a tasks by token dictionary");
    XCTAssertEqual(_sessionController.tasksByIdentifier.count, 1U, @"Should have one task for group");
    XCTAssertNotNil([_sessionController.tasksByIdentifier objectForKey:@(task.taskIdentifier)], @"Should have a task for task identifier");
}

- (void)testAddNilTask
{
    NSURLSessionTask *task;
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:kTestGroupName];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];
    NSArray *tasks = [_sessionController.groups valueForKey:kTestGroupName];
    XCTAssertNil(tasks, @"Should not have a task array for group");
    XCTAssertEqual(_sessionController.tasksByToken.count, 0U, @"Should have one task for group");
    XCTAssertEqual(_sessionController.tasksByIdentifier.count, 0U, @"Should have one task for group");
}

- (void)testAddTaskToNilGroup
{
    NSURLSessionTask *task = [NSURLSessionTask new];
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:nil];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];
    
    XCTAssertEqual(_sessionController.groups.count,
                   1U,
                   @"Should have one task group");
    
    NSArray *tasks = [_sessionController.groups valueForKey:@"kCRSessionControllerGenericTaskGroup"];
   
    XCTAssertNotNil(tasks,
                    @"Should have a generic task group");
    XCTAssertEqual(_sessionController.tasksByToken.count, 1U, @"Should have one task for group");
    XCTAssertEqual(_sessionController.tasksByIdentifier.count, 1U, @"Should have one task for group");
}

- (void)testAddTaskToEmptyStringGroup
{
    NSURLSessionTask *task = [NSURLSessionTask new];
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:@""];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];

    XCTAssertEqual(_sessionController.groups.count,
                   1U,
                   @"Should have one task group");
    
    NSArray *tasks = [_sessionController.groups valueForKey:@"kCRSessionControllerGenericTaskGroup"];
    XCTAssertNotNil(tasks,
                    @"Should not have a task array for group");
}

- (void)testRemoveTask
{
    // Add task first
    NSURLSessionTask *task = [NSURLSessionTask new];
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:kTestGroupName];

    // Remove task
    [_sessionController removeTaskWithToken:kTestTaskToken];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];
    
    XCTAssertEqual(_sessionController.groups.count,
                   0U,
                   @"Should not have task group for tasks when empty");
    
    XCTAssertEqual(_sessionController.tasksByToken.count,
                   0U,
                   @"Should not have any tasks by token when empty");
    
    XCTAssertEqual(_sessionController.tasksByIdentifier.count,
                   0U,
                   @"Should not have any tasks by identifier when empty");
}

- (void)testRemoveTaskFromNilGroup
{
    NSURLSessionTask *task = [NSURLSessionTask new];
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:nil];

    // Remove task
    [_sessionController removeTaskWithToken:kTestTaskToken];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];
    
    XCTAssertEqual(_sessionController.groups.count,
                   0U,
                   @"Should not have task group for tasks when empty");
}

- (void)testTaskWithIdentifier
{
    NSURLSessionTask *task = [NSURLSessionTask new];
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:nil];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];

    NSURLSessionTask *shouldBeTask = [_sessionController taskWithIdentifier:task.taskIdentifier];
    XCTAssertEqualObjects(shouldBeTask, task, @"Tasks should be the same");
    
    [_sessionController removeTaskWithToken:kTestTaskToken];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];

    XCTAssertNil([_sessionController taskWithIdentifier:task.taskIdentifier], @"Should not have a task with task identifier");
}

- (void)testHasTaskWithIdentifier
{
    NSURLSessionTask *task = [NSURLSessionTask new];
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:nil];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];

    XCTAssertTrue([_sessionController hasTaskWithIdentifier:task.taskIdentifier], @"Should have task with identifier");
    
    [_sessionController removeTaskWithToken:kTestTaskToken];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];

    XCTAssertFalse([_sessionController hasTaskWithIdentifier:task.taskIdentifier], @"Should not have task with identifier");
}

- (void)testHasTaskInGroupWithState
{
    NSURLSessionTask *task = [NSURLSessionTask new];
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:kTestGroupName];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];

    XCTAssertTrue([_sessionController hasTasksInGroup:kTestGroupName
                                            withState:NSURLSessionTaskStateRunning],
                  @"Should have task in group with running state");
    
    [_sessionController removeTaskWithToken:kTestTaskToken];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];
    
    XCTAssertFalse([_sessionController hasTasksInGroup:kTestGroupName
                                             withState:NSURLSessionTaskStateRunning],
                  @"Should not have task in group with running state");
}

- (void)testEndToEndHasTaskInGroupWithState
{
    [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
        return YES;
    } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) {
        return [OHHTTPStubsResponse responseWithData:[@"dummyData" dataUsingEncoding:NSUTF8StringEncoding]
                                          statusCode:301
                                             headers:@{@"Location" : @"http://www.nest.com"}];
    }];
    
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];
    
    XCTestExpectation *expectation = [self expectationWithDescription:@"task finished"];
    NSURLSessionDataTask *task = [_sessionController dataTaskForRequest:request
                                                              taskGroup:kTestGroupName
                                                      completionHandler:^(NSData *data,
                                                                          NSURLResponse *response,
                                                                          BOOL cachedResponse,
                                                                          NSError *error) {
                                                          [expectation fulfill];
                                                      }];
    
    XCTAssertTrue([_sessionController hasTasksInGroup:kTestGroupName
                                            withState:NSURLSessionTaskStateSuspended],
                  @"Should have task in group with running state");
    
    [task resume];
    
    XCTAssertTrue([_sessionController hasTasksInGroup:kTestGroupName
                                            withState:NSURLSessionTaskStateRunning],
                  @"Should have task in group with running state");
    
    XCTAssertFalse([_sessionController hasTasksInGroup:kTestGroupName
                                            withState:NSURLSessionTaskStateSuspended],
                  @"Should have task in group with running state");
    
    //
    // Wait until finished
    //
    [self waitForExpectationsWithTimeout:1.0 handler:nil];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];
    
    XCTAssertFalse([_sessionController hasTasksInGroup:kTestGroupName
                                             withState:NSURLSessionTaskStateSuspended],
                   @"Should have task in group with running state");

    XCTAssertFalse([_sessionController hasTasksInGroup:kTestGroupName
                                             withState:NSURLSessionTaskStateRunning],
                   @"Should have task in group with running state");
}

#pragma mark - State Management

- (void)testSuspendTasksInGroup
{
    // Add task first
    NSURLSessionTask *task = [self googleTask];

    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:kTestGroupName];
    
    // Add task first
    NSURLSessionTask *task2 = [NSURLSessionTask new];
    [_sessionController addTask:task
                      withToken:kTestTask2Token
                        toGroup:kTestGroup2Name];
    
    [_sessionController suspendTasksInGroup:kTestGroupName];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];
    
    XCTAssertEqual(task.state,
                   NSURLSessionTaskStateSuspended,
                   @"Task should be suspended");
    
    XCTAssertEqual(task2.state,
                   NSURLSessionTaskStateRunning,
                   @"Task should be running");
}

- (void)testResumeTasksInGroup
{
    NSURLSessionTask *task = [self googleTask];
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:kTestGroupName];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];

    XCTAssertEqual(task.state,
                   NSURLSessionTaskStateSuspended,
                   @"Task should be suspended");
    
    [_sessionController resumeTasksInGroup:kTestGroupName];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];

    XCTAssertEqual(task.state,
                   NSURLSessionTaskStateRunning,
                   @"Task should be running");
}

- (void)testCancelTasksInGroup
{
    NSURLSessionTask *task = [self googleTask];
    
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:kTestGroupName];

    [_sessionController cancelTasksInGroup:kTestGroupName];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];

    XCTAssertEqual(task.state,
                   NSURLSessionTaskStateCanceling,
                   @"Task should be canceled");
}

- (void)testSuspendAllTasks
{
    NSURLSessionTask *task = [self googleTask];
    [task resume];
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:kTestGroupName];
    
    // Add task first
    NSURLSessionTask *task2 = [self googleTask];
    [task2 resume];
    [_sessionController addTask:task2
                      withToken:kTestTask2Token
                        toGroup:kTestGroup2Name];

    [_sessionController suspendAllTasks];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];

    XCTAssertEqual(task.state,
                   NSURLSessionTaskStateSuspended,
                   @"Task should be suspended");
    
    
    XCTAssertEqual(task2.state,
                   NSURLSessionTaskStateSuspended,
                   @"Task should be suspended");
}

- (void)testResumeAllTasks
{
    NSURLSessionTask *task = [self googleTask];
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:kTestGroupName];
    
    // Add task first
    NSURLSessionTask *task2 = [self googleTask];
    [_sessionController addTask:task2
                      withToken:kTestTask2Token
                        toGroup:kTestGroup2Name];
    
    [_sessionController resumeAllTasks];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];

    XCTAssertEqual(task.state,
                   NSURLSessionTaskStateRunning,
                   @"Task should be suspended");
    
    
    XCTAssertEqual(task2.state,
                   NSURLSessionTaskStateRunning,
                   @"Task should be suspended");
}

- (void)testCancelAllTasks
{
    NSURLSessionTask *task = [self googleTask];
    [_sessionController addTask:task
                      withToken:kTestTaskToken
                        toGroup:kTestGroupName];
    
    // Add task first
    NSURLSessionTask *task2 = [self googleTask];
    [_sessionController addTask:task2
                      withToken:kTestTask2Token
                        toGroup:kTestGroup2Name];

    [_sessionController cancelAllTasks];
    [_sessionController.serialQueue waitUntilAllOperationsAreFinished];

    BOOL result = task.state == NSURLSessionTaskStateCanceling
                  || task.state == NSURLSessionTaskStateCompleted;
    
    XCTAssertTrue(result,
                  @"Task should be canceled or completed");
    
    result = task2.state == NSURLSessionTaskStateCanceling
             || task2.state == NSURLSessionTaskStateCompleted;
    
    XCTAssertTrue(result,
                  @"Task should be canceled or completed");
}

#pragma mark - Cache

- (void)testCachedResponse
{
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://drewsmits.com/wp-content/uploads/2013/04/logo.png"]];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    [config.URLCache removeAllCachedResponses];
    config.URLCache = [[NSURLCache alloc] initWithMemoryCapacity:1024 diskCapacity:0 diskPath:nil];
    
    //
    // Stub 200 responses
    //
    [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
        return YES;
    } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) {
        return [OHHTTPStubsResponse responseWithData:[@"dummyData" dataUsingEncoding:NSUTF8StringEncoding]
                                          statusCode:200
                                             headers:nil];
    }];

    CRSessionController *sessionController = [CRSessionController sessionControllerWithConfiguration:config];
    
    __block BOOL taskOneCached = NO;
    
    XCTestExpectation *expectation1 = [self expectationWithDescription:@"task finished"];
    NSURLSessionDataTask *task = [sessionController dataTaskForRequest:request
                                                     completionHandler:^(NSData *data,
                                                                         NSURLResponse *response,
                                                                         BOOL cachedResponse,
                                                                         NSError *error) {
                                                         taskOneCached = cachedResponse;
                                                         [expectation1 fulfill];
                                                     }];
    [task resume];
    
    [self waitForExpectationsWithTimeout:1.0 handler:nil];
    
    __block BOOL taskTwoCached = NO;
    XCTestExpectation *expectation2 = [self expectationWithDescription:@"cached task finished"];
    NSURLSessionDataTask *cachedTask = [sessionController dataTaskForRequest:request
                                                           completionHandler:^(NSData *data,
                                                                               NSURLResponse *response,
                                                                               BOOL cachedResponse,
                                                                               NSError *error) {
                                                               taskTwoCached = cachedResponse;
                                                               [expectation2 fulfill];
                                                           }];
    [cachedTask resume];
    
    [self waitForExpectationsWithTimeout:1.0 handler:nil];
    
    XCTAssertFalse(taskOneCached, @"Response should not be cached");
    XCTAssertTrue(taskTwoCached, @"Response should be cached");
}

@end
