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

import UIKit
import MediaPlayer
import CocoaLumberjack

class LocalMusicLibraryCacheItem {
	let mediaItem: MPMediaItem
	
	lazy var properties: Dictionary<String, Any?> = {
		// The below code currently crashes due to an issue in the Swift implementation of
		// MPMediaItem -enumerateValues(forProperties: using:). We work around by using an
		// Objective-c implementation.
/*		var requiredProperties = Set([MPMediaItemPropertyPersistentID,
									  MPMediaItemPropertyTitle,
									  MPMediaItemPropertyArtist,
									  MPMediaItemPropertyArtistPersistentID,
									  MPMediaItemPropertyAlbumTitle,
									  MPMediaItemPropertyAlbumPersistentID,
									  MPMediaItemPropertyAlbumTrackNumber,
									  MPMediaItemPropertyGenre,
									  MPMediaItemPropertyGenrePersistentID,
									  MPMediaItemPropertyPlaybackDuration])
		
		if #available(iOS 9.2, *) {
			requiredProperties.insert(MPMediaItemPropertyHasProtectedAsset)
		}
		var props = Dictionary<String, Any?> ()
		self.mediaItem.enumerateValues(forProperties: requiredProperties,
									   using: { (key, value, _) in
											props[key] = value
		})
		return props */
		return LocalMusicLibraryCacheItemHelper.properties(for: mediaItem)
	} ()
	
	lazy var id: UInt64 = { return propertyValueAsUnsignedInt64(key: MPMediaItemPropertyPersistentID) } ()
	
	lazy var title: String = {
		return properties[MPMediaItemPropertyTitle] as? String ?? NSLocalizedString("Unknown", comment: "Unknown")
	} ()
	lazy var artist: String = {
		return properties[MPMediaItemPropertyArtist] as? String ?? NSLocalizedString("Unknown", comment: "Unknown")
	} ()
	lazy var albumTitle: String = {
		return properties[MPMediaItemPropertyAlbumTitle] as? String ?? NSLocalizedString("Unknown", comment: "Unknown")
	} ()
	lazy var genre: String = {
		return properties[MPMediaItemPropertyGenre] as? String ?? NSLocalizedString("Unknown", comment: "Unknown")
	} ()
	
	lazy var artistID: UInt64 = { return propertyValueAsUnsignedInt64(key: MPMediaItemPropertyArtistPersistentID) } ()
	lazy var albumID: UInt64 = { return propertyValueAsUnsignedInt64(key: MPMediaItemPropertyAlbumPersistentID) } ()
	lazy var genreID: UInt64 = { return propertyValueAsUnsignedInt64(key: MPMediaItemPropertyGenrePersistentID) } ()
	
	lazy var trackNumber: UInt64 = { return propertyValueAsUnsignedInt64(key: MPMediaItemPropertyAlbumTrackNumber) } ()
	lazy var duration: Double = {
		if let number = properties[MPMediaItemPropertyPlaybackDuration] as? NSNumber {
			return number.doubleValue
		}
		return 0.0
	} ()
	lazy var hasDRM: Bool = {
        var protected = false
		if #available(iOS 9.2, *) {
			if let number = properties[MPMediaItemPropertyHasProtectedAsset] as? NSNumber {
				protected = number.boolValue
			}
		}

        protected = protected || (mediaItem.assetURL == nil)
		return protected
	} ()
	
	init(mediaItem: MPMediaItem) {
		self.mediaItem = mediaItem
	}
}

// MARK: - Public Methods
extension LocalMusicLibraryCacheItem {
	func toMusicLibrarySong() -> MusicLibrarySong {
		return MusicLibrarySong(id: id,
								title: title,
								artist: artist,
								album: albumTitle,
								hasDRM: hasDRM)
	}
}

// MARK: - Private Methods
extension LocalMusicLibraryCacheItem {
	private func propertyValueAsUnsignedInt64(key: String) -> UInt64 {
		if let number = properties[key] as? NSNumber {
			return number.uint64Value
		}
		DDLogWarn("Media Library: Returning zero for \(key) for \(properties)")
		return 0
	}
}

