<commit_before>//
//  URIHandler.swift
//  Pods
//
//  Created by <NAME> on 21/02/17.
//
//

import Foundation

class URIHandler {
    
    internal var scheme: String?
    internal fileprivate(set) var path: String! {
        didSet {
            updatePathComponents()
        }
    }
    internal fileprivate(set) var block: URIHandlerBlock!
    
    fileprivate var pathComponents: [String]!
    
    init(path: String, block: @escaping URIHandlerBlock) {
        self.path = path
        self.block = block
        updatePathComponents()
    }
    
    fileprivate func updatePathComponents() {
        pathComponents = path.components(separatedBy: "/")
    }
    
    func matchURL(_ url: URL, checkScheme: Bool = true) -> Bool {
        
        if checkScheme {
            if let scheme = scheme {
                guard url.scheme == scheme else {
                    return false
                }
            } else {
                guard url.scheme == URIManager.scheme else {
                    return false
                }
            }
        }
        
        var urlPathComponents: [String]
        
        urlPathComponents = url.urlPathComponents(checkScheme: checkScheme)
        
        guard urlPathComponents.count == pathComponents.count else {
            return false
        }
        
        for (index, component) in pathComponents.enumerated() {
            if component.isParameter {
                continue
            }
            if urlPathComponents[index] != component {
                return false
            }
        }
        
        return true
    }
    
    func parametersURL(_ url: URL, checkScheme: Bool) -> [String: String]? {
        
        let urlPathComponents = url.urlPathComponents(checkScheme: checkScheme)
        
        var parameters: [String: String] = [:]
        for (index, component) in pathComponents.enumerated() {
            
            if component.isParameter {
                let parameterName = component.parameterNameString
                parameters[parameterName] = urlPathComponents[index]
            }
            
        }
        
        return parameters.count > 0 ? parameters : nil
    }

}

extension URL {
    
    func urlPathComponents(checkScheme: Bool) -> [String] {
        if checkScheme {
            let pathComponentsString = (host ?? "") + path
            return pathComponentsString.components(separatedBy: "/")
        } else {
            return path.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
                .components(separatedBy: "/")
        }
    }
    
}

extension String {
    
    var isParameter: Bool {
        if let startPlaceholderIndex = range(of: "{"), let endPlaceholderIndex = range(of: "}") {
            let startParenthesisPosition = characters.distance(from: startIndex, to: startPlaceholderIndex.lowerBound)
            let endParenethesisPosition = characters.distance(from: startIndex, to: endPlaceholderIndex.lowerBound)
            if startParenthesisPosition == 0 && endParenethesisPosition == characters.count-1 {
                return true
            }
        }
        return false
    }<commit_msg>Minor fix for Swift 4<commit_after>//
//  URIHandler.swift
//  Pods
//
//  Created by <NAME> on 21/02/17.
//
//

import Foundation

class URIHandler {
    
    internal var scheme: String?
    internal fileprivate(set) var path: String! {
        didSet {
            updatePathComponents()
        }
    }
    internal fileprivate(set) var block: URIHandlerBlock!
    
    fileprivate var pathComponents: [String]!
    
    init(path: String, block: @escaping URIHandlerBlock) {
        self.path = path
        self.block = block
        updatePathComponents()
    }
    
    fileprivate func updatePathComponents() {
        pathComponents = path.components(separatedBy: "/")
    }
    
    func matchURL(_ url: URL, checkScheme: Bool = true) -> Bool {
        
        if checkScheme {
            if let scheme = scheme {
                guard url.scheme == scheme else {
                    return false
                }
            } else {
                guard url.scheme == URIManager.scheme else {
                    return false
                }
            }
        }
        
        var urlPathComponents: [String]
        
        urlPathComponents = url.urlPathComponents(checkScheme: checkScheme)
        
        guard urlPathComponents.count == pathComponents.count else {
            return false
        }
        
        for (index, component) in pathComponents.enumerated() {
            if component.isParameter {
                continue
            }
            if urlPathComponents[index] != component {
                return false
            }
        }
        
        return true
    }
    
    func parametersURL(_ url: URL, checkScheme: Bool) -> [String: String]? {
        
        let urlPathComponents = url.urlPathComponents(checkScheme: checkScheme)
        
        var parameters: [String: String] = [:]
        for (index, component) in pathComponents.enumerated() {
            
            if component.isParameter {
                let parameterName = component.parameterNameString
                parameters[parameterName] = urlPathComponents[index]
            }
            
        }
        
        return parameters.count > 0 ? parameters : nil
    }

}

extension URL {
    
    func urlPathComponents(checkScheme: Bool) -> [String] {
        if checkScheme {
            let pathComponentsString = (host ?? "") + path
            return pathComponentsString.components(separatedBy: "/")
        } else {
            return path.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
                .components(separatedBy: "/")
        }
    }
    
}

extension String {
    
    var isParameter: Bool {
        if let startPlaceholderIndex = range(of: "{"), let endPlaceholderIndex = range(of: "}") {
            let startParenthesisPosition = distance(from: startIndex, to: startPlaceholderIndex.lowerBound)
            let endParenethesisPosition = distance(from: startIndex, to: endPlaceholderIndex.lowerBound)
            if startParenthesisPosition == 0 && endParenethesisPosition == count-1 {
                return true
            }
        }
        return false
    }
{'fraction_non_alphanumeric': 0.08575051513710572, 'fraction_numerical': 0.00301157077191314, 'mean_word_length': 1.6669484361792055, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, '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': '3812420', 'n_tokens_mistral': 1626, 'n_tokens_neox': 1570, 'n_words': 376}