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

import UIKit

class StoreOperationBase: Operation {
	// MARK: Public Properties/Types

	// To keep alive the operation we need to play with the isFinished flag.
	private var myIsFinished: Bool = false
	override var isFinished: Bool {
		get {
			return myIsFinished
		}
		set (newAnswer) {
			willChangeValue(forKey: "isFinished")
			myIsFinished = newAnswer
			didChangeValue(forKey: "isFinished")
		}
	}
}

//MARK: -

class StoreFetchOperation: StoreOperationBase {
	// MARK: Private Properties
	private let id: Int
	private let completion: (Dictionary<String, Any>?) -> Void

	// MARK: Initializer
	init(id: Int,
		 completion: @escaping (Dictionary<String, Any>?) -> Void) {
		self.id = id
		self.completion = completion
	}
}

// MARK: - Overridden Methods
extension StoreFetchOperation {
	override func start() {
		if isCancelled {
			isFinished = true
			return
		}

		let strUrl = "http://itunes.apple.com/lookup?id=\(id)"
		if let url = URL(string: strUrl) {
			URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
				if let data = data,
                    let jsonObj = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary {
					if let results = jsonObj.value(forKey: "results") as? NSArray,
						let firstResult = results.firstObject as? Dictionary<String, Any> {
						self.finish(result: firstResult)
					} else {
						self.finish(result: nil)
					}
				} else {
					self.finish(result: nil)
				}
			}).resume()

		} else {
			finish(result: nil)
		}
	}

	func finish(result: Dictionary<String, Any>?) {
		OperationQueue.main.addOperation {
			self.completion(result)
			self.isFinished = true
		}
	}
}

//MARK: -

class StoreIconOperation: StoreOperationBase {
	// MARK: Private Properties
	private let completion: (UIImage?) -> Void
	private weak var helper: StoreHelper?

	// MARK: Initializer
	init(helper: StoreHelper,
		 completion: @escaping (UIImage?) -> Void) {
		self.helper = helper
		self.completion = completion
	}
}

// MARK: - Overridden Methods
extension StoreIconOperation {
	override func start() {
		if isCancelled {
			isFinished = true
			return
		}

		if let results = helper?.info {
			if let imageURLStr = results["artworkUrl60"] as? String,
				let imageURL = URL(string: imageURLStr) {
				URLSession.shared.dataTask(with: imageURL, completionHandler: { (imgData, imgResponse, imgError) in
					if let imgDataUnwrapped = imgData {
						let image = UIImage(data: imgDataUnwrapped)
						self.finish(result: image)
					} else {
						self.finish(result: nil)
					}
				}).resume()
			} else {
				self.finish(result: nil)
			}
		} else {
			finish(result: nil)
		}
	}

	func finish(result: UIImage?) {
		OperationQueue.main.addOperation {
			self.completion(result)
			self.isFinished = true
		}
	}
}

//MARK: -

class StoreURLOperation: StoreOperationBase {
	// MARK: Private Properties
	private let completion: (URL?) -> Void
	private weak var helper: StoreHelper?

	// MARK: Initializer
	init(helper: StoreHelper,
		 completion: @escaping (URL?) -> Void) {
		self.helper = helper
		self.completion = completion
	}
}

// MARK: - Overridden Methods
extension StoreURLOperation {
	override func start() {
		if isCancelled {
			isFinished = true
			return
		}

		if let results = helper?.info {
			if let appURLStr = results["trackViewUrl"] as? String,
				let appURL = URL(string: appURLStr) {
				self.finish(result: appURL)
			} else {
				self.finish(result: nil)
			}
		} else {
			self.finish(result: nil)
		}
	}

	func finish(result: URL?) {
		OperationQueue.main.addOperation {
			self.completion(result)
			self.isFinished = true
		}
	}
}

//MARK: -

class StoreTitleOperation: StoreOperationBase {
	// MARK: Private Properties
	private let completion: (String?) -> Void
	private weak var helper: StoreHelper?

	// MARK: Initializer
	init(helper: StoreHelper,
		 completion: @escaping (String?) -> Void) {
		self.helper = helper
		self.completion = completion
	}
}

// MARK: - Overridden Methods
extension StoreTitleOperation {
	override func start() {
		if isCancelled {
			isFinished = true
			return
		}

		if let results = helper?.info,
			let title = results["trackName"] as? String {
			self.finish(result: title)
		} else {
			self.finish(result: nil)
		}
	}

	func finish(result: String?) {
		OperationQueue.main.addOperation {
			self.completion(result)
			self.isFinished = true
		}
	}
}

