<commit_before>//
// ConsoleOutputFacility.swift
//
// Copyright © 2016-2017 Netguru Sp. z o.o. All rights reserved.
// Licensed under the MIT License.
//

import Foundation

/// An output facility which outputs requests, responses and errors to console.
@objc(RDTConsoleOutputFacility) public final class ConsoleOutputFacility: NSObject, OutputFacility {

	// MARK: Initializers
	
	/// Initializes the receiver with default print closure.
	public convenience override init() {
		self.init(printClosure: { print($0) })
	}

	/// Initializes the receiver.
	///
	/// - Parameters:
	///     - printClosure: The print closure used to output strings into the
	///       console.
	@objc(initWithPrintBlock:) public init(printClosure: @escaping @convention(block) (String) -> Void) {
		self.printClosure = printClosure
	}

	// MARK: Properties

	/// Print closure used to output strings into the console.
	private let printClosure: @convention(block) (String) -> Void

	// MARK: OutputFacility

	/// Prints the request in the following format:
	///
	///     <0xbadf00d> [REQUEST] POST https://httpbin.org/post
	///      ├─ Headers
	///      │ Content-Type: application/json
	///      │ Content-Length: 14
	///      ├─ Body
	///      │ {
	///      │   "foo": "bar"
	///      │ }
	///
	/// - SeeAlso: OutputFacility.output(requestRepresentation:)
	public func output(requestRepresentation request: RequestRepresentation) {
		let headers = request.headers.reduce([]) {
			$0 + ["\($1.0): \($1.1)"]
		}
		let body = request.deserializedBody.map {
			$0.characters.split { $0 == "\n" }.map(String.init)
		} ?? ["<none>"]
		printBoxString(title: "<\(request.identifier)> [REQUEST] \(request.method) \(request.urlString)", sections: [
			("Headers", headers),
			("Body", body),
		])
	}
	
	/// Prints the response in the following format:
	///
	///     <0xbadf00d> [RESPONSE] 200 (NO ERROR) https://httpbin.org/post
	///      ├─ Headers
	///      │ Content-Type: application/json
	///      │ Content-Length: 24
	///      ├─ Body
	///      │ {
	///      │   "args": {},
	///      │   "headers": {}
	///      │ }
	///
	/// - SeeAlso: OutputFacility.output(responseRepresentation:)
	public func output(responseRepresentation response: ResponseRepresentation) {
		let headers = response.headers.reduce([]) {
			$0 + ["\($1.0): \($1.1)"]
		}
		let body = response.deserializedBody.map {
			$0.characters.split { $0 == "\n" }.map(String.init)
		} ?? ["<none>"]
		printBoxString(title: "<\(response.requestIdentifier)> [RESPONSE] \(response.statusCode) (\(response.statusString.uppercased())) \(response.urlString)", sections: [
			("Headers", headers),
			("Body", body),
		])
	}
	
	/// Prints the error in the following format:
	///
	///     <0xbadf00d> [ERROR] NSURLErrorDomain -1009
	///      ├─ User Info
	///      │ NSLocalizedDescriptionKey: The device is not connected to the internet.
	///      │ NSURLErrorKey: https://httpbin.org/post
	///
	/// - SeeAlso: OutputFacility.output(errorRepresentation:)
	public func output(errorRepresentation error: ErrorRepresentation) {
		let userInfo = error.userInfo.reduce([]) {
			$0 + ["\($1.0): \($1.1)"]<commit_msg>Fix Xcode 9.1 deprecation warnings<commit_after>//
// ConsoleOutputFacility.swift
//
// Copyright © 2016-2017 Netguru Sp. <EMAIL>.o. All rights reserved.
// Licensed under the MIT License.
//

import Foundation

/// An output facility which outputs requests, responses and errors to console.
@objc(RDTConsoleOutputFacility) public final class ConsoleOutputFacility: NSObject, OutputFacility {

	// MARK: Initializers
	
	/// Initializes the receiver with default print closure.
	public convenience override init() {
		self.init(printClosure: { print($0) })
	}

	/// Initializes the receiver.
	///
	/// - Parameters:
	///     - printClosure: The print closure used to output strings into the
	///       console.
	@objc(initWithPrintBlock:) public init(printClosure: @escaping @convention(block) (String) -> Void) {
		self.printClosure = printClosure
	}

	// MARK: Properties

	/// Print closure used to output strings into the console.
	private let printClosure: @convention(block) (String) -> Void

	// MARK: OutputFacility

	/// Prints the request in the following format:
	///
	///     <0xbadf00d> [REQUEST] POST https://httpbin.org/post
	///      ├─ Headers
	///      │ Content-Type: application/json
	///      │ Content-Length: 14
	///      ├─ Body
	///      │ {
	///      │   "foo": "bar"
	///      │ }
	///
	/// - SeeAlso: OutputFacility.output(requestRepresentation:)
	public func output(requestRepresentation request: RequestRepresentation) {
		let headers = request.headers.reduce([]) {
			$0 + ["\($1.0): \($1.1)"]
		}
		let body = request.deserializedBody.map {
			$0.split { $0 == "\n" }.map(String.init)
		} ?? ["<none>"]
		printBoxString(title: "<\(request.identifier)> [REQUEST] \(request.method) \(request.urlString)", sections: [
			("Headers", headers),
			("Body", body),
		])
	}
	
	/// Prints the response in the following format:
	///
	///     <0xbadf00d> [RESPONSE] 200 (NO ERROR) https://httpbin.org/post
	///      ├─ Headers
	///      │ Content-Type: application/json
	///      │ Content-Length: 24
	///      ├─ Body
	///      │ {
	///      │   "args": {},
	///      │   "headers": {}
	///      │ }
	///
	/// - SeeAlso: OutputFacility.output(responseRepresentation:)
	public func output(responseRepresentation response: ResponseRepresentation) {
		let headers = response.headers.reduce([]) {
			$0 + ["\($1.0): \($1.1)"]
		}
		let body = response.deserializedBody.map {
			$0.split { $0 == "\n" }.map(String.init)
		} ?? ["<none>"]
		printBoxString(title: "<\(response.requestIdentifier)> [RESPONSE] \(response.statusCode) (\(response.statusString.uppercased())) \(response.urlString)", sections: [
			("Headers", headers),
			("Body", body),
		])
	}
	
	/// Prints the error in the following format:
	///
	///     <0xbadf00d> [ERROR] NSURLErrorDomain -1009
	///      ├─ User Info
	///      │ NSLocalizedDescriptionKey: The device is not connected to the internet.
	///      │ NSURLErrorKey: https://httpbin.org/post
	///
	/// - SeeAlso: OutputFacility.output(errorRepresentation:)
	public func output(errorRepresentation error: ErrorRepresentation) {
		let userInfo = error.userInfo.reduce([]) {
			$0 + ["\($1.0): \($1.1)"]
{'fraction_non_alphanumeric': 0.17437609283102845, 'fraction_numerical': 0.015577809569225878, 'mean_word_length': 2.792646172393008, 'pattern_counts': {'":': 6, '<': 18, '<?xml version=': 0, '>': 22, 'https://': 6, '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': '5446423', 'n_tokens_mistral': 2188, 'n_tokens_neox': 2046, 'n_words': 508}