@interface ODURLSessionTask()

@property (readonly) NSMutableURLRequest *request;

@end

@implementation ODURLSessionTask

- (instancetype)initWithRequest:(NSMutableURLRequest *)request
                         client:(ODClient *)client
{
    NSParameterAssert(request);
    NSParameterAssert(client);
    
    self = [super init];
    if (self){
        _client = client;
        _request = request;
        _state = ODTaskCreated;
    }
    return self;
}

- (void)execute;
{
    _state = ODTaskAuthenticating;
    [self.client.authProvider appendAuthHeaders:self.request completion:^(NSMutableURLRequest *request, NSError *error){
        if (self.state != ODTaskCanceled){
            if (!error){
                _state = ODTaskExecuting;
                    _innerTask = [self taskWithRequest:request];
                    [self.client.logger logWithLevel:ODLogInfo message:@"Created NSURLSessionTask"];
                    [self.client.logger logWithLevel:ODLogVerbose message:@"Task Id : %ld", _innerTask.taskIdentifier];
                    [_innerTask resume];
                }
            else{
                _state = ODTaskAuthFailed;
                [self.client.logger logWithLevel:ODLogError message:@"Authentication Failed with error :%@", error];
                [self authenticationFailedWithError:error];
            }
        }
    }];
}

- (void)cancel
{
    [self.client.logger logWithLevel:ODLogInfo message:@"Canceled task"];
    if (_innerTask){
        [self.client.logger logWithLevel:ODLogDebug message:@"inner task : %l", [_innerTask taskIdentifier]];
        [_innerTask cancel];
    }
    _state = ODTaskCanceled;
}

- (NSURLSessionTask *)taskWithRequest:(NSMutableURLRequest *)request
{
    NSAssert(YES, @"Not Implemented, must implement in sub class");
    return nil;
}

- (void)authenticationFailedWithError:(NSError *)authError
{
    NSAssert(YES, @"Not Implemented, must implement in sub class");
}

@end
