//
//  AstroFileUtils.swift
//  Astro
//
//  Created by Liz Cross on 2015-05-28.
//  Copyright (c) 2015 Mobify Research & Development Inc. All rights reserved.
//

import Foundation

public struct AstroFileUtils {

    public static func image(filePath string: String, respond: RPCMethodCallback) -> UIImage? {

        guard let url = URL(string: string) else {
            respond(.error("\"\(string)\" is not a valid image URL. Expecting 'file:///image.png'"))
            return nil
        }

        guard url.isFileURL else {
            respond(.error("\"\(string)\" is not a file URL. Expecting 'file:///image.png'"))
            return nil
        }

        guard !url.lastPathComponent.isEmpty else {
            respond(.error("\"\(string)\" does not contain a path component. Expecting 'file:///image.png'"))
            return nil
        }

        guard url.path == "/" + url.lastPathComponent else {
            respond(.error("Invalid image path \(url). Directories not supported. Expecting 'file:///image.png'"))
            return nil
        }

        guard let imageNameUrl = URL(string: url.lastPathComponent) else {
            respond(.error("Couldn't create file url from \(url). Expecting 'file:///image.png'"))
            return nil
        }

        // We should never need to find the file manually in the bundle using the extension
        // because UIImage(named:) should always find it automatically.
        guard let image = UIImage(named: imageNameUrl.deletingPathExtension().absoluteString, in: AstroViewController.mainBundle, compatibleWith: UIScreen.main.traitCollection) else {
            respond(.error("Image at \(url) not found in application bundle."))
            return nil
        }

        return image
    }

    public static func image(path string: String, respond: @escaping RPCMethodCallback, success: @escaping ((UIImage) -> Void)) -> Void {
        guard let url = URL(string: string) else {
            respond(.error("\"\(string)\" is not a valid image URL.  Expecting 'file:///image.png' or 'http://image.png'"))
            return
        }

        if url.isFileURL {
            if let image = image(filePath: string, respond: respond) {
                success(image)
            }
            return
        }

        let task = AstroWebUtils.sharedNetworkSession.dataTask(with: url, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in
            guard error == nil else {
                respond(.error("Image at \(url) could not be loaded, error \(error!.localizedDescription)."))
                return
            }
            guard let response = response as? HTTPURLResponse else {
                respond(.error("Response from \(url) was not a NSHTTPURLResponse."))
                return
            }
            guard response.statusCode == 200 else {
                respond(.error("Image at \(url) not accessible, status code \(response.statusCode)."))
                return
            }
            guard let data = data else {
                respond(.error("File at \(url) could not be loaded. Server returned an empty response."))
                return
            }
            guard let image = UIImage(data: data) else {
                respond(.error("File at \(url) not an image."))
                return
            }

            // Run the completion handler on the main thread, since we'll likely be setting up a UI element with the image
            DispatchQueue.main.async(execute: {
                success(image)
            })
        })
        task.resume()
    }
}
