//
//  Extensions.swift
//  Runner
//
//  Created by ZiKambrani on 04/04/1442 AH.
//

import UIKit


extension String{
    func toUrl() -> URL?{
        return URL(string: self)
    }
    
    func removeSpace() -> String?{
        return self.replacingOccurrences(of: " ", with: "")
    }
}

extension Date{
    func toString(format:String) -> String{
        let df = DateFormatter()
        df.dateFormat = format
        return df.string(from: self)
    }
}

extension Dictionary{
    func merge(dict:[String:Any?]) -> [String:Any?]{
        var self_ = self as! [String:Any?]
        dict.forEach { (kv) in
            self_.updateValue(kv.value, forKey: kv.key)
        }
        return self_
    }
}

extension Bundle {

    func certificate(named name: String) -> SecCertificate {
        let cerURL = self.url(forResource: name, withExtension: "cer")!
        let cerData = try! Data(contentsOf: cerURL)
        let cer = SecCertificateCreateWithData(nil, cerData as CFData)!
        return cer
    }

    func identity(named name: String, password: String) -> SecIdentity {
        let p12URL = self.url(forResource: name, withExtension: "p12")!
        let p12Data = try! Data(contentsOf: p12URL)

        var importedCF: CFArray? = nil
        let options = [kSecImportExportPassphrase as String: password]
        let err = SecPKCS12Import(p12Data as CFData, options as CFDictionary, &importedCF)
        precondition(err == errSecSuccess)
        let imported = importedCF! as NSArray as! [[String:AnyObject]]
        precondition(imported.count == 1)

        return (imported[0][kSecImportItemIdentity as String]!) as! SecIdentity
    }
    
    
}

extension SecCertificate{
    func trust() -> Bool?{
        var optionalTrust: SecTrust?
        let policy = SecPolicyCreateBasicX509()
        
        let status = SecTrustCreateWithCertificates([self] as AnyObject,
                                                    policy,
                                                    &optionalTrust)
        guard status == errSecSuccess else { return false}
        let trust = optionalTrust!
        
        let stat = optionalTrust?.evaluateAllowing(rootCertificates: [self])
        return stat
    }
    
    func secTrustObject() -> SecTrust?{
        var optionalTrust: SecTrust?
        let policy = SecPolicyCreateBasicX509()
        
        let status = SecTrustCreateWithCertificates([self] as AnyObject,
                                                    policy,
                                                    &optionalTrust)
        return optionalTrust
    }
}


extension SecTrust {

    func evaluate() -> Bool {
        var trustResult: SecTrustResultType = .invalid
        let err = SecTrustEvaluate(self, &trustResult)
        guard err == errSecSuccess else { return false }
        return [.proceed, .unspecified].contains(trustResult)
    }

    func evaluateAllowing(rootCertificates: [SecCertificate]) -> Bool {

        // Apply our custom root to the trust object.

        var err = SecTrustSetAnchorCertificates(self, rootCertificates as CFArray)
        guard err == errSecSuccess else { return false }

        // Re-enable the system's built-in root certificates.

        err = SecTrustSetAnchorCertificatesOnly(self, false)
        guard err == errSecSuccess else { return false }

        // Run a trust evaluation and only allow the connection if it succeeds.

        return self.evaluate()
    }
}


extension UIView{
    func show(){
        self.alpha = 0.0
        self.isHidden = false
        UIView.animate(withDuration: 0.25, animations: {
            self.alpha = 1
        }) { (complete) in
            
        }
    }
    
    func hide(){
        UIView.animate(withDuration: 0.25, animations: {
            self.alpha = 0.0
        }) { (complete) in
            self.isHidden = true
        }
    }
}


extension UIViewController{
    func showAlert(withTitle: String, message: String){
        let alert = UIAlertController(title: withTitle, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .destructive, handler: nil))
        present(alert, animated: true) {
            
        }
    }
}

