//
//  FeedSpecifier.swift
//  FeedFinder
//
//  Created by Brent Simmons on 8/7/16.
//  Copyright © 2016 Ranchero Software, LLC. All rights reserved.
//

import Foundation

struct FeedSpecifier: Hashable {

	enum Source: Int {

		case UserEntered = 0, HTMLHead, HTMLLink

		func equalToOrBetterThan(_ otherSource: Source) -> Bool {

			return self.rawValue <= otherSource.rawValue
		}
	}

	public let title: String?
	public let urlString: String
	public let source: Source
	public var score: Int {
		return calculatedScore()
	}
	
	func feedSpecifierByMerging(_ feedSpecifier: FeedSpecifier) -> FeedSpecifier {

		// Take the best data (non-nil title, better source) to create a new feed specifier;

		let mergedTitle = title ?? feedSpecifier.title
		let mergedSource = source.equalToOrBetterThan(feedSpecifier.source) ? source : feedSpecifier.source

		return FeedSpecifier(title: mergedTitle, urlString: urlString, source: mergedSource)
	}
	
	public static func bestFeed(in feedSpecifiers: Set<FeedSpecifier>) -> FeedSpecifier? {
		
		if feedSpecifiers.isEmpty {
			return nil
		}
		if feedSpecifiers.count == 1 {
			return feedSpecifiers.anyObject()
		}
		
		var currentHighScore = Int.min
		var currentBestFeed: FeedSpecifier? = nil
		
		for oneFeedSpecifier in feedSpecifiers {
			let oneScore = oneFeedSpecifier.score
			if oneScore > currentHighScore {
				currentHighScore = oneScore
				currentBestFeed = oneFeedSpecifier
			}
		}
		
		return currentBestFeed
	}
}

private extension FeedSpecifier {
	
	func calculatedScore() -> Int {
		
		var score = 0
		
		if source == .UserEntered {
			return 1000
		}
		else if source == .HTMLHead {
			score = score + 50
		}
		
		if urlString.rs_caseInsensitiveContains("comments") {
			score = score - 10
		}
		if urlString.rs_caseInsensitiveContains("rss") {
			score = score + 5
		}
		if urlString.hasSuffix("/feed/") {
			score = score + 5
		}
		if urlString.hasSuffix("/feed") {
			score = score + 4
		}
		if urlString.rs_caseInsensitiveContains("json") {
			score = score + 6
		}
		
		if let title = title {
			if title.rs_caseInsensitiveContains("comments") {
				score = score - 10
			}
			if title.rs_caseInsensitiveContains("json") {
				score = score + 1
			}
		}
		
		return score
	}
}
