<commit_before>//
//  QRReader.swift
//  Bitcoin.com
//
//  Copyright © 2019 <NAME>
//  Copyright © 2019 Bitcoin Cash Supporters developers
//

// Migration Native to Cordova
// In progress

import UIKit
import AVKit

@objc(QRReader)
class QRReader: CDVPlugin, AVCaptureMetadataOutputObjectsDelegate {
    
    fileprivate var readingCommand: CDVInvokedUrlCommand?
    fileprivate var captureSession: AVCaptureSession!
    fileprivate var previewLayer: AVCaptureVideoPreviewLayer!
    fileprivate var cameraView: UIView!
    
    enum QRReaderError: Int {
        case NO_PERMISSION = 1
        case SCANNING_UNSUPPORTED = 2
    }
    
    override func pluginInitialize() {
        super.pluginInitialize()
        cameraView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
        cameraView.autoresizingMask = [.flexibleWidth, .flexibleHeight];
    }
    
    func startReading(_ command: CDVInvokedUrlCommand){
        
        // Keep the callback
        readingCommand = command
        
        // If it is already initialized or webview missing, return
        
        guard let _ = self.cameraView
            , let webView = self.webView
            , let superView = webView.superview else {
                return
        }
        
        guard self.previewLayer == nil
            , self.captureSession == nil else {
                
            if !self.captureSession.isRunning {
                self.captureSession.startRunning()
            }
            return
        }
        
        cameraView.backgroundColor = UIColor.yellow
        captureSession = AVCaptureSession()
        
        guard let videoCaptureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) else {
            // TODO: Handle the case without permission "Permission"
            failed(QRReaderError.NO_PERMISSION)
            return
        }
        
        let videoInput: AVCaptureDeviceInput
        
        do {
            videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
        } catch {
            // TODO: Handle this case "Retry"
            return
        }
        
        guard captureSession.canAddInput(videoInput) else {
            failed(QRReaderError.SCANNING_UNSUPPORTED)
            return
        }
        captureSession.addInput(videoInput)
        
        let metadataOutput = AVCaptureMetadataOutput()
        
        guard captureSession.canAddOutput(metadataOutput) else {
            failed(QRReaderError.SCANNING_UNSUPPORTED)
            return
        }
        captureSession.addOutput(metadataOutput)
        
        metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
        
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.frame = cameraView.layer.bounds
        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        
        cameraView.layer.addSublayer(previewLayer)
        superView.insertSubview(cameraView, belowSubview: webView)
        
        captureSession.startRunning()
    }
    
    func stopReading(_ command: CDVInvokedUrlCommand){
        captureSession.stopRunning()
    }
    
    func failed(_ error: QRReaderError) {
        print("Scanning unsupported")
        guard let readingCommand = self.readingCommand
            , let callbackId = readingCommand.callbackId
            , let commandDelegate = self.commandDelegate else {
                return
        }
        
        let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: error.rawValue)
        commandDelegate.send(pluginResult, callbackId:callbackId)
    }
    
    func captureOutput(_ output: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
        captureSession.stopRunning()
        
        if let metadataObject = metadataObjects.first {
            guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
            
            guard let result = readableObject.stringValue
                , let readingCommand = self.readingCommand
                , let callbackId = readingCommand.callbackId
                , let commandDelegate = self.commandDelegate else {
                    return
            }
            
            // Vigration to test
            AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
            
            // Callback
            let pluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: result)
            commandDelegate.send(pluginResult, callbackId: callbackId)
            self.readingCommand = nil
        }
    }
}<commit_msg>Refactoring + clean up + add open settings<commit_after>//
//  QRReader.swift
//  Bitcoin.com
//
//  Copyright © 2019 <NAME>
//  Copyright © 2019 Bitcoin Cash Supporters developers
//

// Migration Native to Cordova
// In progress

import UIKit
import AVKit

@objc(QRReader)
class QRReader: CDVPlugin, AVCaptureMetadataOutputObjectsDelegate {
    
    fileprivate var readingCommand: CDVInvokedUrlCommand?
    fileprivate var captureSession: AVCaptureSession!
    fileprivate var previewLayer: AVCaptureVideoPreviewLayer!
    fileprivate var cameraView: UIView!
    
    enum QRReaderError: String {
        case ERROR_NO_PERMISSION
        case ERROR_SCANNING_UNSUPPORTED
        case ERROR_OPEN_SETTINGS_UNAVAILABLE
    }
    
}


// Initialization
//
extension QRReader {
    
    override func pluginInitialize() {
        super.pluginInitialize()
        cameraView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
        cameraView.autoresizingMask = [.flexibleWidth, .flexibleHeight];
    }
    
    func captureOutput(_ output: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
        captureSession.stopRunning()
        
        if let metadataObject = metadataObjects.first {
            guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
            
            guard let result = readableObject.stringValue else {
                return
            }
            
            // Vigration to test
            AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
            
            // Callback
            onSuccess(result)
        }
    }
}

// Expose methods
//
extension QRReader {
    
    func openSettings(_ command: CDVInvokedUrlCommand) {
        guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
            return
        }
        
        if UIApplication.shared.canOpenURL(settingsUrl) {
            UIApplication.shared.open(settingsUrl, completionHandler: { [weak self] (success) in
                self?.callback(command, status: CDVCommandStatus_NO_RESULT)
            })
        }
    }
    
    func startReading(_ command: CDVInvokedUrlCommand){
        
        // Keep the callback
        readingCommand = command
        
        // If it is already initialized or webview missing, return
        
        guard let _ = self.cameraView
            , let webView = self.webView
            , let superView = webView.superview else {
                return
        }
        
        guard self.previewLayer == nil
            , self.captureSession == nil else {
                
                if !self.captureSession.isRunning {
                    self.captureSession.startRunning()
                }
                return
        }
        
        cameraView.backgroundColor = UIColor.white
        captureSession = AVCaptureSession()
        
        guard let videoCaptureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) else {
            // TODO: Handle the case without permission "Permission"
            onFailed(QRReaderError.ERROR_NO_PERMISSION)
            return
        }
        
        let videoInput: AVCaptureDeviceInput
        
        do {
            videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
        } catch {
            // TODO: Handle this case "Retry"
            onFailed(QRReaderError.ERROR_NO_PERMISSION)
            return
        }
        
        guard captureSession.canAddInput(videoInput) else {
            onFailed(QRReaderError.ERROR_SCANNING_UNSUPPORTED)
            return
        }
        captureSession.addInput(videoInput)
        
        let metadataOutput = AVCaptureMetadataOutput()
        
        guard captureSession.canAddOutput(metadataOutput) else {
            onFailed(QRReaderError.ERROR_SCANNING_UNSUPPORTED)
            return
        }
        captureSession.addOutput(metadataOutput)
        
        metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
        
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.frame = cameraView.layer.bounds
        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        
        cameraView.layer.addSublayer(previewLayer)
        superView.insertSubview(cameraView, belowSubview: webView)
        
        captureSession.startRunning()
    }
    
    func stopReading(_ command: CDVInvokedUrlCommand){
        captureSession.stopRunning()
    }
}

// Private methods
//
extension QRReader {
    
    fileprivate func callback(_ command: CDVInvokedUrlCommand, status: CDVCommandStatus) {
        callback(command, status: status, message: nil)
    }
    
    fileprivate func callback(_ command: CDVInvokedUrlCommand, status: CDVCommandStatus, message: String?) {
        guard let callbackId = command.callbackId
            , let commandDelegate = self.commandDelegate else {
                return
        }
        
        var pluginResult: CDVPluginResult
        
        // Callback
        if let _ = message  {
            pluginResult = CDVPluginResult(status: status, messageAs: message)
        } else {
            pluginResult = CDVPluginResult(status: status)
        }
        
        commandDelegate.send(pluginResult, callbackId: callbackId)
    }
    
    func onSuccess(_ result: String) {
        guard let readingCommand = self.readingCommand else {
            return
        }
        
        callback(readingCommand, status: CDVCommandStatus_OK, message: result)
        self.readingCommand = nil
    }
    
    func onFailed(_ error: QRReaderError) {
        guard let readingCommand = self.readingCommand else {
            return
        }
        
        callback(readingCommand, status: CDVCommandStatus_ERROR, message: error.rawValue)
        self.readingCommand = nil
    }
}
{'fraction_non_alphanumeric': 0.06539484545537926, 'fraction_numerical': 0.0020177932679079154, 'mean_word_length': 2.1172098341909664, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '4153724', 'n_tokens_mistral': 2774, 'n_tokens_neox': 2752, 'n_words': 599}