<commit_before>//
//  NetworkUserReportableError.swift
//  SwiftPlusPlus
//
//  Created by <NAME> on 4/24/16.
//  Copyright © 2016 Drewag LLC. All rights reserved.
//

public struct NetworkUserReportableError: UserReportableError {
    public enum Type {
        case Unauthorized
        case NoInternet
        case NotFound
        case Gone
        case Internal(message: String)
        case User(message: String)
    }

    let source: String
    public let operation: String
    public let type: Type
    public let otherInfo: [String : String]?

    public init(source: String, operation: String, type: Type) {
        self.source = source
        self.operation = operation
        self.type = type
        self.otherInfo = nil
    }

    public init(source: String, operation: String, error: NSError) {
        self.source = source
        self.operation = operation
        self.otherInfo = nil
        if error.domain == "NSURLErrorDomain" && error.code == -1009 {
            self.type = .NoInternet
        }
        else {
            self.type = .Internal(message: error.localizedDescription)
        }
    }

    public init?(source: String, operation: String, response: NSHTTPURLResponse?, data: NSData?) {
        self.source = source
        self.operation = operation
        if let response = response {
            switch response.statusCode ?? 0 {
            case 404:
                self.type = .NotFound
                self.otherInfo = nil
            case 401:
                self.type = .Unauthorized
                self.otherInfo = nil
            case 410:
                self.type = .Gone
                self.otherInfo = nil
            case let x where x >= 400 && x < 500:
                if let data = data {
                    (self.type, self.otherInfo) = NetworkUserReportableError.typeAndOtherInfo(fromData: data, andResponse: response)
                }
                else {
                    self.type = .User(message: "Invalid request")
                    self.otherInfo = nil
                }
            case let x where x >= 500 && x < 600:
                if let data = data {
                    (self.type, self.otherInfo) = NetworkUserReportableError.typeAndOtherInfo(fromData: data, andResponse: response)
                }
                else {
                    self.type = .Internal(message: "Unknown error")
                    self.otherInfo = nil
                }
            default:
                return nil
            }
        }
        else {
            return nil
        }
    }

    public var alertTitle: String {
        switch self.type {
        case .User:
            return "Problem \(self.operation)"
        case .Internal:
            return "Internal Error"
        case .NoInternet:
            return "No Interent Connection"
        case .Unauthorized:
            return "Unauthorized"
        case .NotFound:
            return "Endpoint not found"
        case .Gone:
            return "App Out of Date"
        }
    }

    public var alertMessage: String {
        switch self.type {
        case .Internal(let message):
            return "Please try again. If the problem persists please contact support with the following description: \(message)"
        case .User(let message):
            return message
        case .NoInternet:
            return "Please make sure you are connected to the internet and try again"
        case .Unauthorized:
            return "You have been signed out. Please sign in again."
        case .NotFound:
            return "Please try again. If the problem persists please contact support"
        case .Gone:
            return "This app is out of date. Please update to the latest version."
        }
    }
}

private extension NetworkUserReportableError {
    static func typeAndOtherInfo(fromData data: NSData, andResponse response: NSHTTPURLResponse) -> (type: Type, otherInfo: [String:String]?){
        let encoding: NSStringEncoding
        if let encodingName = response.textEncodingName {
            encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding(encodingName))
        }
        else {
            encoding = NSUTF8StringEncoding
        }<commit_msg>[NF] Added a network error type for an untrusted server<commit_after>//
//  NetworkUserReportableError.swift
//  SwiftPlusPlus
//
//  Created by <NAME> on 4/24/16.
//  Copyright © 2016 Drewag LLC. All rights reserved.
//

public struct NetworkUserReportableError: UserReportableError {
    public enum Type {
        case Unauthorized
        case NoInternet
        case NotFound
        case Gone
        case Untrusted
        case Internal(message: String)
        case User(message: String)
    }

    let source: String
    public let operation: String
    public let type: Type
    public let otherInfo: [String : String]?

    public init(source: String, operation: String, type: Type) {
        self.source = source
        self.operation = operation
        self.type = type
        self.otherInfo = nil
    }

    public init(source: String, operation: String, error: NSError) {
        self.source = source
        self.operation = operation
        self.otherInfo = nil
        if error.domain == "NSURLErrorDomain" {
            switch error.code {
            case -1009:
                self.type = .NoInternet
            case -999:
                self.type = .Untrusted
            default:
                self.type = .Internal(message: error.localizedDescription)

            }
        }
        else {
            self.type = .Internal(message: error.localizedDescription)
        }
    }

    public init?(source: String, operation: String, response: NSHTTPURLResponse?, data: NSData?) {
        self.source = source
        self.operation = operation
        if let response = response {
            switch response.statusCode ?? 0 {
            case 404:
                self.type = .NotFound
                self.otherInfo = nil
            case 401:
                self.type = .Unauthorized
                self.otherInfo = nil
            case 410:
                self.type = .Gone
                self.otherInfo = nil
            case let x where x >= 400 && x < 500:
                if let data = data {
                    (self.type, self.otherInfo) = NetworkUserReportableError.typeAndOtherInfo(fromData: data, andResponse: response)
                }
                else {
                    self.type = .User(message: "Invalid request")
                    self.otherInfo = nil
                }
            case let x where x >= 500 && x < 600:
                if let data = data {
                    (self.type, self.otherInfo) = NetworkUserReportableError.typeAndOtherInfo(fromData: data, andResponse: response)
                }
                else {
                    self.type = .Internal(message: "Unknown error")
                    self.otherInfo = nil
                }
            default:
                return nil
            }
        }
        else {
            return nil
        }
    }

    public var alertTitle: String {
        switch self.type {
        case .User:
            return "Problem \(self.operation)"
        case .Internal:
            return "Internal Error"
        case .NoInternet:
            return "No Interent Connection"
        case .Unauthorized:
            return "Unauthorized"
        case .NotFound:
            return "Endpoint not found"
        case .Gone:
            return "App Out of Date"
        case .Untrusted:
            return "Untrusted Web Server"
        }
    }

    public var alertMessage: String {
        switch self.type {
        case .Internal(let message):
            return "Please try again. If the problem persists please contact support with the following description: \(message)"
        case .User(let message):
            return message
        case .NoInternet:
            return "Please make sure you are connected to the internet and try again"
        case .Unauthorized:
            return "You have been signed out. Please sign in again."
        case .NotFound:
            return "Please try again. If the problem persists please contact support"
        case .Gone:
            return "This app is out of date. Please update to the latest version."
        case .Untrusted:
            return "The web server can no longer be trusted. Please update to the latest version. If this problem still occures please contact us immediately."
        }
    }
}

private extension NetworkUserReportableError {
    static func typeAndOtherInfo(fromData data: NSData, andResponse response: NSHTTPURLResponse) -> (type: Type, otherInfo: [String:String]?){
        let encoding: NSStringEncoding
        if let encodingName = response.textEncodingName {
            encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding(encodingName))
        }
        else {
            encoding = NSUTF8StringEncoding
        }
{'fraction_non_alphanumeric': 0.07404537908135031, 'fraction_numerical': 0.008301051466519093, 'mean_word_length': 1.6483001172332943, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, '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': '1451564', 'n_tokens_mistral': 2326, 'n_tokens_neox': 2176, 'n_words': 727}