#import "AtomDataSource.h"

#import "BSAtomParser/BSAtomParser.h"
#import "BSAtomParser/BSAtomFeed.h"
#import "BSAtomParser/BSAtomFeedEntry.h"
#import "BSAtomParser/BSAtomFeedCustomElement.h"
#import "BSAtomParser/BSAtomFeedLink.h"



@implementation AtomDataSource {
	BSAtomFeed * _feed;
	NSMutableArray * _entries;
	NSMutableDictionary * _contents;
}


- (void)setURLString:(NSString *)URLString {
	_URLString = [URLString copy];
	_dataString = nil;
	[self load];
}

- (void)setDataString:(NSString *)dataString {
	_dataString = [dataString copy];
	_URLString = nil;
	[self load];
}

- (void)clear {
	_feed = nil;
}

- (void)load {
	
	if (self.URLString) {
		[self sendRequestForURLFromString:self.URLString
					  completion:^(NSURLResponse * response, NSData * data, NSError * error) {
						  if (error) return;
						  [self parseFeed:data];
					  }];
	}
	else if (self.dataString) {
		[self parseFeed:[self.dataString dataUsingEncoding:NSUTF8StringEncoding]];
	}
	
}

- (BOOL)didLoad {
	return _feed != nil;
}

- (void)parseFeed:(NSData *)feedData {
	[self parseFeed:feedData appendEntries:NO];
}

- (void)parseFeed:(NSData *)feedData appendEntries:(BOOL)append {
	if (!append || !_entries)
		_entries = [[NSMutableArray alloc] init];
	[[BSAtomParser parser] parseAtomFeedWithData:feedData delegate:(id<BSAtomParserDelegate>)self];
}

- (id)contents {
	return _contents;
}

- (NSArray *)items {
	return _entries;
}


#pragma mark - DataSourceBase methods

- (NSInteger)numberOfSections {
	if (!self.didLoad) return 0;
	return 1;
}

- (NSInteger)numberOfItemsInSection:(NSInteger)section {
	if (!self.didLoad) return 0;
	return _entries.count;
}

- (NSDictionary *)datasetForItemAtIndexPath:(NSIndexPath *)indexPath {
	if (indexPath.item >= _entries.count) return nil;
	BSAtomFeedEntry * entry = _entries[indexPath.item];
	return entry.dictionaryRepresentation;
}


#pragma mark - BSAtomParser delegate

- (void)atomParser:(BSAtomParser *)parser didParseAtomFeedEntry:(BSAtomFeedEntry *)entry {
	[_entries addObject:entry];
}

- (void)atomParser:(BSAtomParser *)parser didParseAtomFeed:(BSAtomFeed *)feed {
	_feed = feed;
	
	_contents = @{
				  }.mutableCopy;
	if (feed.title.content) _contents[@"title"] = feed.title.content;
	if (feed.subtitle.content) _contents[@"subtitle"] = feed.subtitle.content;
	if (feed.rights.content) _contents[@"rights"] = feed.rights.content;
	_contents[@"entries"] = @[].mutableCopy;
	for (BSAtomFeedEntry * entry in _entries) {
		[_contents[@"entries"] addObject:entry.dictionaryRepresentation];
	}
	if (feed.links.count) _contents[@"link"] = ((BSAtomFeedLink *)[feed.links objectAtIndex:0]).href;
	
	[self notifyObservers];
}

- (void)atomParser:(BSAtomParser *)parser didFailWithError:(NSError *)error {
	NSLog(@"Error parsing feed: %@", error);
}


#pragma mark - Pagination

- (NSString *)nextLink {
	NSString * __block nextLink = nil;
	[_feed.links enumerateObjectsUsingBlock:^(BSAtomFeedLink * linkInfo, NSUInteger idx, BOOL *stop) {
		if ([linkInfo.rel isEqualToString:@"next"]) {
			nextLink = linkInfo.href;
			*stop = YES;
		}
	}];
	return nextLink;
}

- (BOOL)canLoadMore {
	NSString * nextLink = [self nextLink];
	return nextLink.length;
}

- (void)loadMore {
	
	NSString * nextLink = [self nextLink];
	if (!nextLink.length) return;
	
	[self sendRequestForURLFromString:nextLink
							completion:^(NSURLResponse * response, NSData * data, NSError * error) {
								if (error) return;
								[self parseFeed:data appendEntries:YES];
							}];
	
}

@end
