/* Copyright (c) 2010 Google Inc.
 *
 * 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.
 */

//
//  GTMHTTPFetcherService.m
//

#import "GTMHTTPFetcherService.h"

@interface GTMHTTPFetcher (ServiceMethods)
- (BOOL)beginFetchMayDelay:(BOOL)mayDelay
              mayAuthorize:(BOOL)mayAuthorize;
@end

@interface GTMHTTPFetcherService ()
@property (retain, readwrite) NSDictionary *delayedHosts;
@property (retain, readwrite) NSDictionary *runningHosts;

- (void)detachAuthorizer;
@end

@implementation GTMHTTPFetcherService

@synthesize maxRunningFetchersPerHost = maxRunningFetchersPerHost_,
            userAgent = userAgent_,
            timeout = timeout_,
            delegateQueue = delegateQueue_,
            runLoopModes = runLoopModes_,
            credential = credential_,
            proxyCredential = proxyCredential_,
            cookieStorageMethod = cookieStorageMethod_,
            shouldFetchInBackground = shouldFetchInBackground_,
            allowedInsecureSchemes = allowedInsecureSchemes_,
            allowLocalhostRequest = allowLocalhostRequest_,
            fetchHistory = fetchHistory_;

- (id)init {
  self = [super init];
  if (self) {
    fetchHistory_ = [[GTMHTTPFetchHistory alloc] init];
    delayedHosts_ = [[NSMutableDictionary alloc] init];
    runningHosts_ = [[NSMutableDictionary alloc] init];
    cookieStorageMethod_ = kGTMHTTPFetcherCookieStorageMethodFetchHistory;

    maxRunningFetchersPerHost_ = 10;
}
  return self;
}

- (void)dealloc {
  [self detachAuthorizer];

  [delayedHosts_ release];
  [runningHosts_ release];
  [fetchHistory_ release];
  [userAgent_ release];
  [delegateQueue_ release];
  [runLoopModes_ release];
  [credential_ release];
  [proxyCredential_ release];
  [authorizer_ release];
  [allowedInsecureSchemes_ release];

  [super dealloc];
}

#pragma mark Generate a new fetcher

- (id)fetcherWithRequest:(NSURLRequest *)request
            fetcherClass:(Class)fetcherClass {
  GTMHTTPFetcher *fetcher = [fetcherClass fetcherWithRequest:request];

  fetcher.fetchHistory = self.fetchHistory;
  fetcher.delegateQueue = self.delegateQueue;
  fetcher.runLoopModes = self.runLoopModes;
  fetcher.cookieStorageMethod = self.cookieStorageMethod;
  fetcher.credential = self.credential;
  fetcher.proxyCredential = self.proxyCredential;
  fetcher.shouldFetchInBackground = self.shouldFetchInBackground;
  fetcher.allowedInsecureSchemes = self.allowedInsecureSchemes;
  fetcher.allowLocalhostRequest = self.allowLocalhostRequest;
  fetcher.authorizer = self.authorizer;
  fetcher.service = self;

  NSString *userAgent = self.userAgent;
  if ([userAgent length] > 0
      && [request valueForHTTPHeaderField:@"User-Agent"] == nil) {
    [fetcher.mutableRequest setValue:userAgent
                  forHTTPHeaderField:@"User-Agent"];
  }

  NSTimeInterval timeout = self.timeout;
  if (timeout > 0.0) {
    [fetcher.mutableRequest setTimeoutInterval:timeout];
  }

  return fetcher;
}

- (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request {
  return [self fetcherWithRequest:request
                     fetcherClass:[GTMHTTPFetcher class]];
}

- (GTMHTTPFetcher *)fetcherWithURL:(NSURL *)requestURL {
  return [self fetcherWithRequest:[NSURLRequest requestWithURL:requestURL]];
}

- (GTMHTTPFetcher *)fetcherWithURLString:(NSString *)requestURLString {
  return [self fetcherWithURL:[NSURL URLWithString:requestURLString]];
}

#pragma mark Queue Management

- (void)addRunningFetcher:(GTMHTTPFetcher *)fetcher
                  forHost:(NSString *)host {
  // Add to the array of running fetchers for this host, creating the array
  // if needed
  NSMutableArray *runningForHost = [runningHosts_ objectForKey:host];
  if (runningForHost == nil) {
    runningForHost = [NSMutableArray arrayWithObject:fetcher];
    [runningHosts_ setObject:runningForHost forKey:host];
  } else {
    [runningForHost addObject:fetcher];
  }
}

- (void)addDelayedFetcher:(GTMHTTPFetcher *)fetcher
                  forHost:(NSString *)host {
  // Add to the array of delayed fetchers for this host, creating the array
  // if needed
  NSMutableArray *delayedForHost = [delayedHosts_ objectForKey:host];
  if (delayedForHost == nil) {
    delayedForHost = [NSMutableArray arrayWithObject:fetcher];
    [delayedHosts_ setObject:delayedForHost forKey:host];
  } else {
    [delayedForHost addObject:fetcher];
  }
}

- (BOOL)isDelayingFetcher:(GTMHTTPFetcher *)fetcher {
  @synchronized(self) {
    NSString *host = [[[fetcher mutableRequest] URL] host];
    NSArray *delayedForHost = [delayedHosts_ objectForKey:host];
    NSUInteger idx = [delayedForHost indexOfObjectIdenticalTo:fetcher];
    BOOL isDelayed = (delayedForHost != nil) && (idx != NSNotFound);
    return isDelayed;
  }
}

- (BOOL)fetcherShouldBeginFetching:(GTMHTTPFetcher *)fetcher {
  // Entry point from the fetcher
  @synchronized(self) {
    NSURL *requestURL = [[fetcher mutableRequest] URL];
    NSString *host = [requestURL host];

    // Addresses "file:///path" case where localhost is the implicit host.
    if ([host length] == 0 && [requestURL isFileURL]) {
      host = @"localhost";
    }

    if ([host length] == 0) {
#if DEBUG
      // Data URIs legitimately have no host, reject other hostless URLs.
      NSAssert1([[requestURL scheme] isEqual:@"data"], @"%@ lacks host", fetcher);
#endif
      return YES;
    }

    NSMutableArray *runningForHost = [runningHosts_ objectForKey:host];
    if (runningForHost != nil
        && [runningForHost indexOfObjectIdenticalTo:fetcher] != NSNotFound) {
#if DEBUG
      NSAssert1(0, @"%@ was already running", fetcher);
#endif
      return YES;
    }

    // We'll save the host that serves as the key for this fetcher's array
    // to avoid any chance of the underlying request changing, stranding
    // the fetcher in the wrong array
    fetcher.serviceHost = host;
    fetcher.thread = [NSThread currentThread];

    if (maxRunningFetchersPerHost_ == 0
        || maxRunningFetchersPerHost_ > [runningForHost count]) {
      [self addRunningFetcher:fetcher forHost:host];
      return YES;
    } else {
      [self addDelayedFetcher:fetcher forHost:host];
      return NO;
    }
  }
  return YES;
}

// Fetcher start and stop methods, invoked on the appropriate thread for
// the fetcher
- (void)performSelector:(SEL)sel onStartThreadForFetcher:(GTMHTTPFetcher *)fetcher {
  NSOperationQueue *delegateQueue = fetcher.delegateQueue;
  NSThread *thread = fetcher.thread;
  if (delegateQueue != nil || [thread isEqual:[NSThread currentThread]]) {
    // The fetcher should run on the thread we're on now, or there's a delegate
    // queue specified so it doesn't matter what thread the fetcher is started
    // on, since it will call back on the queue.
    [self performSelector:sel withObject:fetcher];
  } else {
    // Fetcher must run on a specified thread (and that thread must have a
    // run loop.)
    [self performSelector:sel
                 onThread:thread
               withObject:fetcher
            waitUntilDone:NO];
  }
}

- (void)startFetcherOnCurrentThread:(GTMHTTPFetcher *)fetcher {
  [fetcher beginFetchMayDelay:NO
                 mayAuthorize:YES];
}

- (void)startFetcher:(GTMHTTPFetcher *)fetcher {
  [self performSelector:@selector(startFetcherOnCurrentThread:)
    onStartThreadForFetcher:fetcher];
}

- (void)stopFetcherOnCurrentThread:(GTMHTTPFetcher *)fetcher {
  [fetcher stopFetching];
}

- (void)stopFetcher:(GTMHTTPFetcher *)fetcher {
  [self performSelector:@selector(stopFetcherOnCurrentThread:)
    onStartThreadForFetcher:fetcher];
}

- (void)fetcherDidStop:(GTMHTTPFetcher *)fetcher {
  // Entry point from the fetcher
  @synchronized(self) {
    NSString *host = fetcher.serviceHost;
    if (!host) {
      // fetcher has been stopped previously
      return;
    }

    NSMutableArray *runningForHost = [runningHosts_ objectForKey:host];
    [runningForHost removeObject:fetcher];

    NSMutableArray *delayedForHost = [delayedHosts_ objectForKey:host];
    [delayedForHost removeObject:fetcher];

    while ([delayedForHost count] > 0
           && [runningForHost count] < maxRunningFetchersPerHost_) {
      // Start another delayed fetcher running, scanning for the minimum
      // priority value, defaulting to FIFO for equal priorities
      GTMHTTPFetcher *nextFetcher = nil;
      for (GTMHTTPFetcher *delayedFetcher in delayedForHost) {
        if (nextFetcher == nil
            || delayedFetcher.servicePriority < nextFetcher.servicePriority) {
          nextFetcher = delayedFetcher;
        }
      }

      if (nextFetcher) {
        [self addRunningFetcher:nextFetcher forHost:host];
        runningForHost = [runningHosts_ objectForKey:host];

        [delayedForHost removeObjectIdenticalTo:nextFetcher];
        [self startFetcher:nextFetcher];
      }
    }

    if ([runningForHost count] == 0) {
      // None left; remove the empty array
      [runningHosts_ removeObjectForKey:host];
    }

    if ([delayedForHost count] == 0) {
      [delayedHosts_ removeObjectForKey:host];
    }

    // The fetcher is no longer in the running or the delayed array,
    // so remove its host and thread properties
    fetcher.serviceHost = nil;
    fetcher.thread = nil;
  }
}

- (NSUInteger)numberOfFetchers {
  @synchronized(self) {
    NSUInteger running = [self numberOfRunningFetchers];
    NSUInteger delayed = [self numberOfDelayedFetchers];
    return running + delayed;
  }
}

- (NSUInteger)numberOfRunningFetchers {
  @synchronized(self) {
    NSUInteger sum = 0;
    for (NSString *host in runningHosts_) {
      NSArray *fetchers = [runningHosts_ objectForKey:host];
      sum += [fetchers count];
    }
    return sum;
  }
}

- (NSUInteger)numberOfDelayedFetchers {
  @synchronized(self) {
    NSUInteger sum = 0;
    for (NSString *host in delayedHosts_) {
      NSArray *fetchers = [delayedHosts_ objectForKey:host];
      sum += [fetchers count];
    }
    return sum;
  }
}

- (NSArray *)issuedFetchersWithRequestURL:(NSURL *)requestURL {
  @synchronized(self) {
    NSMutableArray *array = nil;
    NSString *host = [requestURL host];
    if ([host length] == 0) return nil;

    NSURL *absRequestURL = [requestURL absoluteURL];

    NSArray *runningForHost = [runningHosts_ objectForKey:host];
    for (GTMHTTPFetcher *fetcher in runningForHost) {
      NSURL *fetcherURL = [[[fetcher mutableRequest] URL] absoluteURL];
      if ([fetcherURL isEqual:absRequestURL]) {
        if (array == nil) {
          array = [NSMutableArray array];
        }
        [array addObject:fetcher];
      }
    }

    NSArray *delayedForHost = [delayedHosts_ objectForKey:host];
    for (GTMHTTPFetcher *fetcher in delayedForHost) {
      NSURL *fetcherURL = [[[fetcher mutableRequest] URL] absoluteURL];
      if ([fetcherURL isEqual:absRequestURL]) {
        if (array == nil) {
          array = [NSMutableArray array];
        }
        [array addObject:fetcher];
      }
    }
    return array;
  }
}

- (void)stopAllFetchers {
  @synchronized(self) {
    // Remove fetchers from the delayed list to avoid fetcherDidStop: from
    // starting more fetchers running as a side effect of stopping one
    NSArray *delayedForHosts = [delayedHosts_ allValues];
    [delayedHosts_ removeAllObjects];

    for (NSArray *delayedForHost in delayedForHosts) {
      for (GTMHTTPFetcher *fetcher in delayedForHost) {
        [self stopFetcher:fetcher];
      }
    }

    NSArray *runningForHosts = [runningHosts_ allValues];
    [runningHosts_ removeAllObjects];

    for (NSArray *runningForHost in runningForHosts) {
      for (GTMHTTPFetcher *fetcher in runningForHost) {
        [self stopFetcher:fetcher];
      }
    }
  }
}

#pragma mark Fetch History Settings

// Turn on data caching to receive a copy of previously-retrieved objects.
// Otherwise, fetches may return status 304 (No Change) rather than actual data
- (void)setShouldCacheETaggedData:(BOOL)flag {
  self.fetchHistory.shouldCacheETaggedData = flag;
}

- (BOOL)shouldCacheETaggedData {
  return self.fetchHistory.shouldCacheETaggedData;
}

- (void)setETaggedDataCacheCapacity:(NSUInteger)totalBytes {
  self.fetchHistory.memoryCapacity = totalBytes;
}

- (NSUInteger)ETaggedDataCacheCapacity {
  return self.fetchHistory.memoryCapacity;
}

- (void)setShouldRememberETags:(BOOL)flag {
  self.fetchHistory.shouldRememberETags = flag;
}

- (BOOL)shouldRememberETags {
  return self.fetchHistory.shouldRememberETags;
}

// reset the ETag cache to avoid getting a Not Modified status
// based on prior queries
- (void)clearETaggedDataCache {
  [self.fetchHistory clearETaggedDataCache];
}

- (void)clearHistory {
  [self clearETaggedDataCache];
  [self.fetchHistory removeAllCookies];
}

#pragma mark Synchronous Wait for Unit Testing

- (void)waitForCompletionOfAllFetchersWithTimeout:(NSTimeInterval)timeoutInSeconds {
  NSDate* giveUpDate = [NSDate dateWithTimeIntervalSinceNow:timeoutInSeconds];
  BOOL isMainThread = [NSThread isMainThread];

  while ([self numberOfFetchers] > 0
         && [giveUpDate timeIntervalSinceNow] > 0) {
    // Run the current run loop 1/1000 of a second to give the networking
    // code a chance to work
    if (isMainThread || delegateQueue_ == nil) {
      NSDate *stopDate = [NSDate dateWithTimeIntervalSinceNow:0.001];
      [[NSRunLoop currentRunLoop] runUntilDate:stopDate];
    } else {
      // Sleep on the delegate queue's background thread.
      [NSThread sleepForTimeInterval:0.001];
    }
  }
}

#pragma mark Accessors

- (NSDictionary *)runningHosts {
  return runningHosts_;
}

- (void)setRunningHosts:(NSDictionary *)dict {
  [runningHosts_ autorelease];
  runningHosts_ = [dict mutableCopy];
}

- (NSDictionary *)delayedHosts {
  return delayedHosts_;
}

- (void)setDelayedHosts:(NSDictionary *)dict {
  [delayedHosts_ autorelease];
  delayedHosts_ = [dict mutableCopy];
}

- (id <GTMFetcherAuthorizationProtocol>)authorizer {
  return authorizer_;
}

- (void)setAuthorizer:(id <GTMFetcherAuthorizationProtocol>)obj {
  if (obj != authorizer_) {
    [self detachAuthorizer];
  }

  [authorizer_ autorelease];
  authorizer_ = [obj retain];

  // Use the fetcher service for the authorization fetches if the auth
  // object supports fetcher services
  if ([authorizer_ respondsToSelector:@selector(setFetcherService:)]) {
#if GTM_USE_SESSION_FETCHER
    [authorizer_ setFetcherService:(id)self];
#else
    [authorizer_ setFetcherService:self];
#endif
  }
}

- (void)detachAuthorizer {
  // This method is called by the fetcher service's dealloc and setAuthorizer:
  // methods; do not override.
  //
  // The fetcher service retains the authorizer, and the authorizer has a
  // weak pointer to the fetcher service (a non-zeroing pointer for
  // compatibility with iOS 4 and Mac OS X 10.5/10.6.)
  //
  // When this fetcher service no longer uses the authorizer, we want to remove
  // the authorizer's dependence on the fetcher service.  Authorizers can still
  // function without a fetcher service.
  if ([authorizer_ respondsToSelector:@selector(fetcherService)]) {
    id authFetcherService = [authorizer_ fetcherService];
    if (authFetcherService == self) {
      [authorizer_ setFetcherService:nil];
    }
  }
}

@end
