<commit_before>//
// Created by <NAME> on 2019-03-07.
// Copyright (c) 2019 spark. All rights reserved.
//

import Foundation

class StepEnsureHasInternetAccess : MeshSetupStep {
    private var checkDeviceHasIPStartTime: Date?
    private var checkSimActiveRetryCount: Int = 0

    override func start() {
        guard let context = self.context else {
            return
        }

        context.delegate.meshSetupDidEnterState(self, state: .TargetDeviceConnectingToInternetStarted)

        if (context.targetDevice.isSetupDone == nil || context.targetDevice.isSetupDone! == false) {
            self.setDeviceSetupDone()
        } else if (context.targetDevice.hasActiveInternetInterface() &&
                context.targetDevice.activeInternetInterface! == .ppp &&
                (context.targetDevice.sim!.active == nil || context.targetDevice.sim!.active! == false)) {
            self.activateSim()
        } else if (context.targetDevice.isListeningMode == nil || context.targetDevice.isListeningMode! == true) {
            self.stopTargetDeviceListening()
        } else if (context.targetDevice.hasInternetAddress == nil || context.targetDevice.hasInternetAddress! == false) {
            self.checkDeviceHasIP()
        } else {
            self.stepCompleted()
        }

    }

    override func reset() {
        self.checkDeviceHasIPStartTime = nil
        self.checkSimActiveRetryCount = 0
    }

    private func setDeviceSetupDone() {
        guard let context = self.context else {
            return
        }

        context.targetDevice.transceiver!.sendDeviceSetupDone (done: true) { [weak self, weak context] result in
            guard let self = self, let context = context, !context.canceled else {
                return
            }

            self.log("targetDevice.transceiver!.sendDeviceSetupDone: \(result.description())")

            if (result == .NONE) {
                context.targetDevice.isSetupDone = true
                self.start()
            } else {
                self.handleBluetoothErrorResult(result)
            }
        }
    }


    private func activateSim() {
        guard let context = self.context else {
            return
        }

        if (self.checkSimActiveRetryCount > MeshSetup.activateSimRetryCount) {
            self.checkSimActiveRetryCount = 0
            self.fail(withReason: .FailedToActivateSim)
            return
        }
        self.checkSimActiveRetryCount += 1

        ParticleCloud.sharedInstance().updateSim(context.targetDevice.sim!.iccid!, action: .activate, dataLimit: nil, countryCode: nil, cardToken: nil) {
            [weak self, weak context] error in

            guard let self = self, let context = context, !context.canceled else {
                return
            }

            self.log("updateSim error: \(error)")

            if let nsError = error as? NSError, nsError.code == 504 {
                self.log("activate sim returned 504, but that is fine :(")
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(1)) {
                    self.start()
                }
            } else if (error != nil) {
                self.fail(withReason: .FailedToActivateSim, nsError: error!)
                return
            } else {
                context.targetDevice.sim!.active = true
                context.delegate.meshSetupDidEnterState(self, state: .TargetDeviceConnectingToInternetStep0Done)
                self.start()
            }
        }
    }

    private func stopTargetDeviceListening() {
        guard let context = self.context else {
            return
        }

        context.targetDevice.transceiver!.sendStopListening { [weak self, weak context] result in
            guard let self = self, let context = context, !context.canceled else {
                return
            }

            self.log("targetDevice.sendStopListening: \(result.description())")

            if (result == .NONE) {
                context.targetDevice.isListeningMode = false
                self.start()
            } else {
                self.handleBluetoothErrorResult(result)
            }
        }
    }


    private func checkDeviceHasIP() {
        guard let context = self.context else {
            return
        }

        if (self.checkDeviceHasIPStartTime == nil) {
            self.checkDeviceHasIPStartTime = Date()
        }

        let diff = Date().timeIntervalSince(self.checkDeviceHasIPStartTime!)

        //simActive is going to be not nil only if cellular flow
        let limit = (context.targetDevice.sim!.active != nil) ? MeshSetup.deviceObtainedIPCellularTimeout : MeshSetup.deviceObtainedIPTimeout

        if (diff > limit) {
            self.checkDeviceHasIPStartTime = nil

            if (context.targetDevice.sim?.active != nil) {
                self.fail(withReason: .FailedToObtainIpBoron)
            } else {
                self.fail(withReason: .FailedToObtainIp)
            }
            return
        }

        context.targetDevice.transceiver!.sendGetInterface(interfaceIndex: context.targetDevice.getActiveNetworkInterfaceIdx()!) {
            [weak self, weak context] result, interface in
            guard let self = self, let context = context, !context.canceled else {
                return
            }

            self.log("result: \(result.description()), networkInfo: \(interface as Optional)")

            if (result == .NONE) {
                if (interface?.ipv4Config.addresses.first != nil || interface?.ipv6Config.addresses.first != nil) {
                    context.targetDevice.hasInternetAddress = true
                    self.start()<commit_msg>fix a crash when setting up wifi credentials in mesh setup<commit_after>//
// Created by <NAME> on 2019-03-07.
// Copyright (c) 2019 spark. All rights reserved.
//

import Foundation

class StepEnsureHasInternetAccess : MeshSetupStep {
    private var checkDeviceHasIPStartTime: Date?
    private var checkSimActiveRetryCount: Int = 0

    override func start() {
        guard let context = self.context else {
            return
        }

        context.delegate.meshSetupDidEnterState(self, state: .TargetDeviceConnectingToInternetStarted)

        if (context.targetDevice.isSetupDone == nil || context.targetDevice.isSetupDone! == false) {
            self.setDeviceSetupDone()
        } else if (context.targetDevice.hasActiveInternetInterface() &&
                context.targetDevice.activeInternetInterface! == .ppp &&
                (context.targetDevice.sim!.active == nil || context.targetDevice.sim!.active! == false)) {
            self.activateSim()
        } else if (context.targetDevice.isListeningMode == nil || context.targetDevice.isListeningMode! == true) {
            self.stopTargetDeviceListening()
        } else if (context.targetDevice.hasInternetAddress == nil || context.targetDevice.hasInternetAddress! == false) {
            self.checkDeviceHasIP()
        } else {
            self.stepCompleted()
        }

    }

    override func reset() {
        self.checkDeviceHasIPStartTime = nil
        self.checkSimActiveRetryCount = 0
    }

    private func setDeviceSetupDone() {
        guard let context = self.context else {
            return
        }

        context.targetDevice.transceiver!.sendDeviceSetupDone (done: true) { [weak self, weak context] result in
            guard let self = self, let context = context, !context.canceled else {
                return
            }

            self.log("targetDevice.transceiver!.sendDeviceSetupDone: \(result.description())")

            if (result == .NONE) {
                context.targetDevice.isSetupDone = true
                self.start()
            } else {
                self.handleBluetoothErrorResult(result)
            }
        }
    }


    private func activateSim() {
        guard let context = self.context else {
            return
        }

        if (self.checkSimActiveRetryCount > MeshSetup.activateSimRetryCount) {
            self.checkSimActiveRetryCount = 0
            self.fail(withReason: .FailedToActivateSim)
            return
        }
        self.checkSimActiveRetryCount += 1

        ParticleCloud.sharedInstance().updateSim(context.targetDevice.sim!.iccid!, action: .activate, dataLimit: nil, countryCode: nil, cardToken: nil) {
            [weak self, weak context] error in

            guard let self = self, let context = context, !context.canceled else {
                return
            }

            self.log("updateSim error: \(error)")

            if let nsError = error as? NSError, nsError.code == 504 {
                self.log("activate sim returned 504, but that is fine :(")
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(1)) {
                    self.start()
                }
            } else if (error != nil) {
                self.fail(withReason: .FailedToActivateSim, nsError: error!)
                return
            } else {
                context.targetDevice.sim!.active = true
                context.delegate.meshSetupDidEnterState(self, state: .TargetDeviceConnectingToInternetStep0Done)
                self.start()
            }
        }
    }

    private func stopTargetDeviceListening() {
        guard let context = self.context else {
            return
        }

        context.targetDevice.transceiver!.sendStopListening { [weak self, weak context] result in
            guard let self = self, let context = context, !context.canceled else {
                return
            }

            self.log("targetDevice.sendStopListening: \(result.description())")

            if (result == .NONE) {
                context.targetDevice.isListeningMode = false
                self.start()
            } else {
                self.handleBluetoothErrorResult(result)
            }
        }
    }


    private func checkDeviceHasIP() {
        guard let context = self.context else {
            return
        }

        if (self.checkDeviceHasIPStartTime == nil) {
            self.checkDeviceHasIPStartTime = Date()
        }

        let diff = Date().timeIntervalSince(self.checkDeviceHasIPStartTime!)

        //simActive is going to be not nil only if cellular flow
        let limit = (context.targetDevice.sim?.active != nil) ? MeshSetup.deviceObtainedIPCellularTimeout : MeshSetup.deviceObtainedIPTimeout

        if (diff > limit) {
            self.checkDeviceHasIPStartTime = nil

            if (context.targetDevice.sim?.active != nil) {
                self.fail(withReason: .FailedToObtainIpBoron)
            } else {
                self.fail(withReason: .FailedToObtainIp)
            }
            return
        }

        context.targetDevice.transceiver!.sendGetInterface(interfaceIndex: context.targetDevice.getActiveNetworkInterfaceIdx()!) {
            [weak self, weak context] result, interface in
            guard let self = self, let context = context, !context.canceled else {
                return
            }

            self.log("result: \(result.description()), networkInfo: \(interface as Optional)")

            if (result == .NONE) {
                if (interface?.ipv4Config.addresses.first != nil || interface?.ipv6Config.addresses.first != nil) {
                    context.targetDevice.hasInternetAddress = true
                    self.start()
{'fraction_non_alphanumeric': 0.09383495571340875, 'fraction_numerical': 0.00456020345523108, 'mean_word_length': 1.9429677419354838, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, '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': '821465', 'n_tokens_mistral': 3015, 'n_tokens_neox': 2850, 'n_words': 647}