//
// © 2017-2020 Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.
//

import UIKit

struct PersistedMediaItem: Codable {
    var streamURL: String = ""
    var thumbnailURL: String = ""
    var title: String = ""
    var artist: String = ""
    var album: String = ""
    var genre: String = ""
    var country: String = ""
    var subtitle: String = ""
    var duration: Int32 = 0
    var userData: String = ""
    var customHTTPHeaders: [String] = []
    
    init (item: IoTMediaItem) {
        streamURL = item.streamURL
        thumbnailURL = item.thumbnailURL
        title = item.title
        artist = item.artist
        album = item.album
        genre = item.genre
        country = item.country
        duration = item.duration
        userData = item.userData
        customHTTPHeaders = [String] ()
    }
}

// MARK: - Public Methods
extension PersistedMediaItem {
    func mediaItem() -> IoTMediaItem? {
        let item = IoTMediaItem()
		
		// When generating media items for use in the app we try to update URL in case IP changed.
        item.streamURL = HTTPServer.sharedInstance.refreshURLIfLocal(url: streamURL)
        item.thumbnailURL = HTTPServer.sharedInstance.refreshURLIfLocal(url: thumbnailURL)
        item.title = title
        item.artist = artist
        item.album = album
        item.genre = genre
        item.country = country
        item.duration = duration
        item.userData = userData
        return item
    }
    
	func represents(mediaItem: IoTMediaItem) -> Bool {
		let persistedIsLocal = HTTPServer.sharedInstance.isLocalAssetURL(streamURL)
		let mediaItemIsLocal = HTTPServer.sharedInstance.isLocalAssetURL(mediaItem.streamURL)
		
		if persistedIsLocal != mediaItemIsLocal {
			return false
		}
		
		return hashForMediaItem(mediaItem) == hashValue
    }
}

// MARK: - Private Methods
extension PersistedMediaItem {
	private func hashForMediaItem(_ mediaItem: IoTMediaItem) -> Int {
		// Although the media item implementation implements Hashable (and uses the same method below), to
		// rely on it would be fragile and depend on a weak contract. We reimplement it here to ensure consistency in this
		// file
		guard HTTPServer.sharedInstance.isLocalAssetURL(mediaItem.streamURL),
			let (id, _) = HTTPServer.sharedInstance.parseLocalAssetURL(mediaItem.streamURL) else {
				// Not local
				return mediaItem.title.hashValue ^ mediaItem.artist.hashValue ^
					mediaItem.album.hashValue ^ mediaItem.genre.hashValue ^ mediaItem.streamURL.hashValue
		}
		return id.hashValue
	}
}

// MARK: - Hashable Conformance
extension PersistedMediaItem: Hashable {
    static func ==(lhs: PersistedMediaItem, rhs: PersistedMediaItem) -> Bool {
        return lhs.hashValue == rhs.hashValue
    }

    func hash(into hasher: inout Hasher) {
        guard HTTPServer.sharedInstance.isLocalAssetURL(streamURL),
            let (id, _) = HTTPServer.sharedInstance.parseLocalAssetURL(streamURL) else {
                // Not local
                hasher.combine(title)
                hasher.combine(subtitle)
                hasher.combine(artist)
                hasher.combine(album)
                hasher.combine(genre)
                hasher.combine(streamURL)
                return
        }
        hasher.combine(id)
    }
}

