<commit_before>//
//  ImgixClient.swift
//  imgix-swift
//
//  Created by <NAME> on 6/30/16.
//
//

import Foundation

@objc open class ImgixClient: NSObject {
    static open let VERSION = "0.3.0"

    open let host: String
    open var useHttps: Bool = true
    open var secureUrlToken: String? = nil
    open var includeLibraryParam: Bool = true

    public init(host: String) {
        self.host = host
    }

    public init(host: String, useHttps: Bool) {
        self.host = host
        self.useHttps = useHttps
    }

    public init(host: String, useHttps: Bool, secureUrlToken: String) {
        self.host = host
        self.useHttps = useHttps
        self.secureUrlToken = secureUrlToken
    }

    public init(host: String, secureUrlToken: String) {
        self.host = host
        self.secureUrlToken = secureUrlToken
    }

    open func buildUrl(_ path: String, params: NSDictionary) -> URL {
        let path = sanitizePath(path)

        var urlComponents = URLComponents.init()
        urlComponents.scheme = useHttps ? "https" : "http"
        urlComponents.host = self.host
        urlComponents.percentEncodedPath = path
        urlComponents.queryItems = buildParams(params)

        if secureUrlToken != nil {
            let signature = signatureForPathAndQueryString(path, queryString: encodeQueryItems(urlComponents.queryItems!))
            urlComponents.queryItems?.append(signature)
        }

        if urlComponents.queryItems!.isEmpty {
            urlComponents.queryItems = nil
        } else {
            urlComponents.percentEncodedQuery = encodeQueryItems(urlComponents.queryItems!)
        }

        return urlComponents.url!
    }

    open func buildUrl(_ path: String) -> URL {
        return buildUrl(path, params: NSDictionary())
    }

    open func reconstruct(originalURL: URL, params: NSDictionary) -> URL {
        let originalURLComponents = URLComponents(url: originalURL, resolvingAgainstBaseURL: false)
        let mergedParams = NSMutableDictionary()

        if let originalURLQueryItems = originalURLComponents?.queryItems {
            for queryItem in originalURLQueryItems {
                mergedParams.setValue(queryItem.value, forKey: queryItem.name)
            }
        }

        mergedParams.addEntries(from: params as! [AnyHashable : Any])

        let generatedURL = buildUrl(originalURL.path, params: mergedParams)

        var outputURLComponents = URLComponents(url: generatedURL, resolvingAgainstBaseURL: false)!

        outputURLComponents.host = originalURL.host
        outputURLComponents.scheme = originalURL.scheme
        outputURLComponents.port = originalURL.port

        return outputURLComponents.url!
    }

    open func reconstruct(originalURL: URL) -> URL {
        return reconstruct(originalURL: originalURL, params: [:])
    }

    fileprivate func sanitizePath(_ path: String) -> String {
        var path = path

        if path.hasPrefix("http://") || path.hasPrefix("https://") {
            path = path.ixEncodeUriComponent()
        }

        if !path.hasPrefix("/") {
            path = "/" + path
        }

        return path
    }

    fileprivate func encodeQueryItems(_ queryItems: [URLQueryItem]) -> String {
        var queryPairs = [String]()

        for queryItem in queryItems {
            let encodedKey = queryItem.name.ixEncodeUriComponent()
            let encodedVal = queryItem.value!.ixEncodeUriComponent()
            queryPairs.append(encodedKey + "=" + encodedVal)
        }

        return queryPairs.joined(separator: "&")
    }

    fileprivate func buildParams(_ params: NSDictionary) -> [URLQueryItem] {
        let params: NSMutableDictionary = NSMutableDictionary.init(dictionary: params)
        var queryItems = [URLQueryItem]()

        if (includeLibraryParam) {
            params.setValue("swift-" + ImgixClient.VERSION, forKey: "ixlib")
        }

        for (key, val) in params {
            let stringKey = String(describing: key)
            var stringVal = String(describing: val)

            if stringKey.hasSuffix("64") {
                stringVal = stringVal.ixEncode64()
            }

            let queryItem = URLQueryItem.init(name: stringKey, value: stringVal)

            queryItems.append(queryItem)
        }

        return queryItems
    }

    fileprivate func signatureForPathAndQueryString(_ path: String, queryString: String) -> URLQueryItem {
        var signatureBase = secureUrlToken! + path

        if queryString.characters.count > 0 {
            signatureBase += "?" + queryString
        }

        let signature = signatureBase.ixMd5

        return URLQueryItem.init(name: "s", value: signature)<commit_msg>Make ImgixClient Swift 4 compliant<commit_after>//
//  ImgixClient.swift
//  imgix-swift
//
//  Created by <NAME> on 6/30/16.
//
//

import Foundation

@objc open class ImgixClient: NSObject {
    @objc static open let VERSION = "0.3.0"

    @objc open let host: String
    @objc open var useHttps: Bool = true
    @objc open var secureUrlToken: String? = nil
    @objc open var includeLibraryParam: Bool = true

    @objc public init(host: String) {
        self.host = host
    }

    @objc public init(host: String, useHttps: Bool) {
        self.host = host
        self.useHttps = useHttps
    }

    @objc public init(host: String, useHttps: Bool, secureUrlToken: String) {
        self.host = host
        self.useHttps = useHttps
        self.secureUrlToken = secureUrlToken
    }

    @objc public init(host: String, secureUrlToken: String) {
        self.host = host
        self.secureUrlToken = secureUrlToken
    }

    @objc open func buildUrl(_ path: String, params: NSDictionary) -> URL {
        let path = sanitizePath(path)

        var urlComponents = URLComponents.init()
        urlComponents.scheme = useHttps ? "https" : "http"
        urlComponents.host = self.host
        urlComponents.percentEncodedPath = path
        urlComponents.queryItems = buildParams(params)

        if secureUrlToken != nil {
            let signature = signatureForPathAndQueryString(path, queryString: encodeQueryItems(urlComponents.queryItems!))
            urlComponents.queryItems?.append(signature)
        }

        if urlComponents.queryItems!.isEmpty {
            urlComponents.queryItems = nil
        } else {
            urlComponents.percentEncodedQuery = encodeQueryItems(urlComponents.queryItems!)
        }

        return urlComponents.url!
    }

    @objc open func buildUrl(_ path: String) -> URL {
        return buildUrl(path, params: NSDictionary())
    }

    @objc open func reconstruct(originalURL: URL, params: NSDictionary) -> URL {
        let originalURLComponents = URLComponents(url: originalURL, resolvingAgainstBaseURL: false)
        let mergedParams = NSMutableDictionary()

        if let originalURLQueryItems = originalURLComponents?.queryItems {
            for queryItem in originalURLQueryItems {
                mergedParams.setValue(queryItem.value, forKey: queryItem.name)
            }
        }

        mergedParams.addEntries(from: params as! [AnyHashable : Any])

        let generatedURL = buildUrl(originalURL.path, params: mergedParams)

        var outputURLComponents = URLComponents(url: generatedURL, resolvingAgainstBaseURL: false)!

        outputURLComponents.host = originalURL.host
        outputURLComponents.scheme = originalURL.scheme
        outputURLComponents.port = originalURL.port

        return outputURLComponents.url!
    }

    @objc open func reconstruct(originalURL: URL) -> URL {
        return reconstruct(originalURL: originalURL, params: [:])
    }

    fileprivate func sanitizePath(_ path: String) -> String {
        var path = path

        if path.hasPrefix("http://") || path.hasPrefix("https://") {
            path = path.ixEncodeUriComponent()
        }

        if !path.hasPrefix("/") {
            path = "/" + path
        }

        return path
    }

    fileprivate func encodeQueryItems(_ queryItems: [URLQueryItem]) -> String {
        var queryPairs = [String]()

        for queryItem in queryItems {
            let encodedKey = queryItem.name.ixEncodeUriComponent()
            let encodedVal = queryItem.value!.ixEncodeUriComponent()
            queryPairs.append(encodedKey + "=" + encodedVal)
        }

        return queryPairs.joined(separator: "&")
    }

    fileprivate func buildParams(_ params: NSDictionary) -> [URLQueryItem] {
        let params: NSMutableDictionary = NSMutableDictionary.init(dictionary: params)
        var queryItems = [URLQueryItem]()

        if (includeLibraryParam) {
            params.setValue("swift-" + ImgixClient.VERSION, forKey: "ixlib")
        }

        for (key, val) in params {
            let stringKey = String(describing: key)
            var stringVal = String(describing: val)

            if stringKey.hasSuffix("64") {
                stringVal = stringVal.ixEncode64()
            }

            let queryItem = URLQueryItem.init(name: stringKey, value: stringVal)

            queryItems.append(queryItem)
        }

        return queryItems
    }

    fileprivate func signatureForPathAndQueryString(_ path: String, queryString: String) -> URLQueryItem {
        var signatureBase = secureUrlToken! + path

        if !queryString.isEmpty {
            signatureBase += "?" + queryString
        }

        let signature = signatureBase.ixMd5

        return URLQueryItem.init(name: "s", value: signature)
{'fraction_non_alphanumeric': 0.09297411516111992, 'fraction_numerical': 0.0029582673005810883, 'mean_word_length': 2.435934664246824, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 22, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2940439', 'n_tokens_mistral': 2685, 'n_tokens_neox': 2539, 'n_words': 617}