<commit_before>//
//  ScanService.swift
//  SmartReceipts
//
//  Created by <NAME> on 01/11/2017.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import RxSwift
import SwiftyJSON

fileprivate let PUSH_TIMEOUT: RxTimeInterval = 15
fileprivate let NETWORK_TIMEOUT: RxTimeInterval = 10
fileprivate let RECOGNITION_KEY = "recognition"

class ScanService {
    private var s3Service: S3Service!
    private var recognitionAPI: RecognitionAPI!
    private var pushNotificationService: PushNotificationService!
    private var authService: AuthServiceInterface!
    private var scansPurchaseTracker: ScansPurchaseTracker!
    fileprivate let statusSubject = PublishSubject<ScanStatus>()
    
    init(s3Service: S3Service,
         recognitionAPI: RecognitionAPI,
         pushService: PushNotificationService,
         authService: AuthServiceInterface,
         scansPurchaseTracker: ScansPurchaseTracker)
    {
        self.s3Service = s3Service
        self.recognitionAPI = recognitionAPI
        self.pushNotificationService = pushService
        self.authService = authService
        self.scansPurchaseTracker = scansPurchaseTracker
    }
    
    convenience init(){
        self.init(s3Service: S3Service(),
                  recognitionAPI: RecognitionAPI(),
                  pushService: PushNotificationService.shared,
                  authService: AuthService.shared,
                  scansPurchaseTracker: ScansPurchaseTracker.shared)
    }
    
    var status: Observable<ScanStatus> {
        return statusSubject.asObservable()
    }
    
    func scan(image: UIImage) -> Observable<Scan> {
        let doc = ReceiptDocument.makeDocumentFrom(image: image)
        return scan(document: doc)
    }
    
    func checkScanAvailable(receiptDocument: ReceiptDocument) -> Observable<Scan>? {
        if WBPreferences.automaticScansEnabled() && FeatureFlags.ocrSupport.isEnabled &&
            authService.isLoggedIn && scansPurchaseTracker.hasAvailableScans {
            pushNotificationService.updateToken()
            statusSubject.onNext(.uploading)
        
            return nil
        } else {
            let isFeatureEnabled = "isFeatureEnabled = \(FeatureFlags.ocrSupport.isEnabled)"
            let isLoggedIn = "isLoggedIn = \(AuthService.shared.isLoggedIn)"
            let hasAvailableScans = "hasAvailableScans = \(ScansPurchaseTracker.shared.hasAvailableScans)"
            let authScansEabled = "authScansEabled = \(ScansPurchaseTracker.shared.hasAvailableScans)"
            Logger.debug("Ignoring OCR: \(isFeatureEnabled), \(isLoggedIn), \(hasAvailableScans), \(authScansEabled).")
            statusSubject.onNext(.completed)
            
            
            return Observable.just(Scan(filepath: receiptDocument.localURL!))
        }
    }
    
    func scan(document: ReceiptDocument) -> Observable<Scan> {
        if let url = document.localURL {
            guard let scanCheck = checkScanAvailable(receiptDocument: document) else {
                return scanFrom(uploading: s3Service.upload(file: url), document: document)
            }
            return scanCheck
        } else {
            return Observable<Scan>.just(Scan(image: UIImage()))
        }
    }
    
    private func scanFrom(uploading: Observable<URL>, document: ReceiptDocument) -> Observable<Scan> {
        return uploading
            .do(onSubscribed: { AnalyticsManager.sharedManager.record(event: Event.ocrRequestStarted()) })
            .do(onError: { _ in
                _ = AuthService.shared.getUser().subscribe(onNext: { CognitoService().saveCognitoData(user: $0) })
            }).flatMap({ [weak self] url -> Observable<String> in
                guard let api = self?.recognitionAPI else {
                    self?.statusSubject.onNext(.completed)
                    return Observable<String>.never()
                }
                self?.statusSubject.onNext(.scanning)
                return api.recognize(url: url, incognito: !WBPreferences.allowSaveImageForAccuracy())
            }).flatMap({ [weak self] id -> Observable<String> in
                if let recognition = self?.getRecognitionID(id: id) { return recognition }
                return Observable.just(id)
            }).flatMap({ [weak self] id -> Observable<Scan> in<commit_msg>Removed checkScanAvailable from ScanService<commit_after>//
//  ScanService.swift
//  SmartReceipts
//
//  Created by <NAME> on 01/11/2017.
//  Copyright © 2017 Will Baumann. All rights reserved.
//

import RxSwift
import SwiftyJSON

fileprivate let PUSH_TIMEOUT: RxTimeInterval = 15
fileprivate let NETWORK_TIMEOUT: RxTimeInterval = 10
fileprivate let RECOGNITION_KEY = "recognition"

class ScanService {
    private var s3Service: S3Service!
    private var recognitionAPI: RecognitionAPI!
    private var pushNotificationService: PushNotificationService!
    private var authService: AuthServiceInterface!
    private var scansPurchaseTracker: ScansPurchaseTracker!
    fileprivate let statusSubject = PublishSubject<ScanStatus>()
    
    init(s3Service: S3Service,
         recognitionAPI: RecognitionAPI,
         pushService: PushNotificationService,
         authService: AuthServiceInterface,
         scansPurchaseTracker: ScansPurchaseTracker)
    {
        self.s3Service = s3Service
        self.recognitionAPI = recognitionAPI
        self.pushNotificationService = pushService
        self.authService = authService
        self.scansPurchaseTracker = scansPurchaseTracker
    }
    
    convenience init(){
        self.init(s3Service: S3Service(),
                  recognitionAPI: RecognitionAPI(),
                  pushService: PushNotificationService.shared,
                  authService: AuthService.shared,
                  scansPurchaseTracker: ScansPurchaseTracker.shared)
    }
    
    var status: Observable<ScanStatus> {
        return statusSubject.asObservable()
    }
    
    func scan(image: UIImage) -> Observable<Scan> {
        let doc = ReceiptDocument.makeDocumentFrom(image: image)
        return scan(document: doc)
    }
    
    func scan(document: ReceiptDocument) -> Observable<Scan> {
        guard let url = document.localURL else { return Observable<Scan>.just(Scan(image: UIImage())) }
        
        if WBPreferences.automaticScansEnabled() && FeatureFlags.ocrSupport.isEnabled &&
            authService.isLoggedIn && scansPurchaseTracker.hasAvailableScans {
            pushNotificationService.updateToken()
            statusSubject.onNext(.uploading)
            
            return scanFrom(uploading: s3Service.upload(file: url), document: document)
        } else {
            let isFeatureEnabled = "isFeatureEnabled = \(FeatureFlags.ocrSupport.isEnabled)"
            let isLoggedIn = "isLoggedIn = \(AuthService.shared.isLoggedIn)"
            let hasAvailableScans = "hasAvailableScans = \(ScansPurchaseTracker.shared.hasAvailableScans)"
            let authScansEabled = "authScansEabled = \(ScansPurchaseTracker.shared.hasAvailableScans)"
            Logger.debug("Ignoring OCR: \(isFeatureEnabled), \(isLoggedIn), \(hasAvailableScans), \(authScansEabled).")
            statusSubject.onNext(.completed)
            
            return Observable.just(Scan(filepath: document.localURL!))
        }
    }
    
    private func scanFrom(uploading: Observable<URL>, document: ReceiptDocument) -> Observable<Scan> {
        return uploading
            .do(onSubscribed: { AnalyticsManager.sharedManager.record(event: Event.ocrRequestStarted()) })
            .do(onError: { _ in
                _ = AuthService.shared.getUser().subscribe(onNext: { CognitoService().saveCognitoData(user: $0) })
            }).flatMap({ [weak self] url -> Observable<String> in
                guard let api = self?.recognitionAPI else {
                    self?.statusSubject.onNext(.completed)
                    return Observable<String>.never()
                }
                self?.statusSubject.onNext(.scanning)
                return api.recognize(url: url, incognito: !WBPreferences.allowSaveImageForAccuracy())
            }).flatMap({ [weak self] id -> Observable<String> in
                if let recognition = self?.getRecognitionID(id: id) { return recognition }
                return Observable.just(id)
            }).flatMap({ [weak self] id -> Observable<Scan> in
{'fraction_non_alphanumeric': 0.09135713427094602, 'fraction_numerical': 0.0062507512922226225, 'mean_word_length': 2.6379536510712724, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 42, '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': '1546411', 'n_tokens_mistral': 2260, 'n_tokens_neox': 2155, 'n_words': 451}