<commit_before>//
//  LiveObserver.swift
//  WWDC
//
//  Created by <NAME> on 13/05/17.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import Foundation
import ConfCore
import RealmSwift
import CloudKit
import os.log

final class LiveObserver: NSObject {

    private let log = OSLog(subsystem: "WWDC", category: "LiveObserver")
    private let dateProvider: DateProvider
    private let storage: Storage
    private let syncEngine: SyncEngine

    private var refreshTimer: Timer?

    var isRunning = false

    private let specialEventsObserver: CloudKitLiveObserver

    init(dateProvider: @escaping DateProvider, storage: Storage, syncEngine: SyncEngine) {
        self.dateProvider = dateProvider
        self.storage = storage
        self.syncEngine = syncEngine
        specialEventsObserver = CloudKitLiveObserver(storage: storage)
    }

    var isWWDCWeek: Bool {
        return storage.realm.objects(Event.self).filter("startDate <= %@ AND endDate > %@ ", dateProvider(), dateProvider()).count > 0
    }

    func start() {
        guard !isRunning else { return }

        os_log("start()", log: log, type: .debug)

        clearLiveSessions()

        specialEventsObserver.fetch()

        guard isWWDCWeek else {
            os_log("Not starting the live event observer because WWDC is not this week",
                   log: log,
                   type: .debug)

            isRunning = false
            return
        }

        isRunning = true

        refreshTimer = Timer.scheduledTimer(withTimeInterval: Constants.liveSessionCheckInterval, repeats: true, block: { [weak self] _ in
            self?.checkForLiveSessions()
        })
        refreshTimer?.tolerance = Constants.liveSessionCheckTolerance
    }

    /// Clears the live flag for all live sessions
    private func clearLiveSessions() {
        storage.modify(allLiveInstances.toArray()) { instances in
            instances.forEach { instance in
                instance.isCurrentlyLive = false
                instance.isForcedLive = false
            }
        }
    }

    func refresh() {
        NSObject.cancelPreviousPerformRequests(withTarget: self)
        perform(#selector(checkForLiveSessions), with: nil, afterDelay: 0)
    }

    private var allLiveInstances: Results<SessionInstance> {
        return storage.realm.objects(SessionInstance.self).filter("isCurrentlyLive == true")
    }

    @objc private func checkForLiveSessions() {
        os_log("checkForLiveSessions()", log: log, type: .debug)

        specialEventsObserver.fetch()

        syncEngine.syncLiveVideos { [weak self] in
            self?.updateLiveFlags()
        }
    }

    private func updateLiveFlags() {
        guard let startTime = Calendar.current.date(byAdding: DateComponents(minute: Constants.liveSessionStartTimeTolerance), to: dateProvider()) else {
            os_log("Could not compute a start time to check for live sessions!", log: log, type: .fault)
            return
        }

        let previouslyLiveInstances = allLiveInstances.toArray()
        var notLiveAnymore: [SessionInstance] = []

        os_log("Looking for live instances with startTime <= %{public}@", log: log, type: .debug, String(describing: startTime))

        let liveInstances = storage.realm.objects(SessionInstance.self).filter("startTime <= %@ AND SUBQUERY(session.assets, $asset, $asset.rawAssetType == %@ AND $asset.actualEndDate == nil).@count > 0", startTime, SessionAssetType.liveStreamVideo.rawValue)
<commit_msg>Considering end time when fetching live sessions<commit_after>//
//  LiveObserver.swift
//  WWDC
//
//  Created by <NAME> on 13/05/17.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import Foundation
import ConfCore
import RealmSwift
import CloudKit
import os.log

final class LiveObserver: NSObject {

    private let log = OSLog(subsystem: "WWDC", category: "LiveObserver")
    private let dateProvider: DateProvider
    private let storage: Storage
    private let syncEngine: SyncEngine

    private var refreshTimer: Timer?

    var isRunning = false

    private let specialEventsObserver: CloudKitLiveObserver

    init(dateProvider: @escaping DateProvider, storage: Storage, syncEngine: SyncEngine) {
        self.dateProvider = dateProvider
        self.storage = storage
        self.syncEngine = syncEngine
        specialEventsObserver = CloudKitLiveObserver(storage: storage)
    }

    var isWWDCWeek: Bool {
        return storage.realm.objects(Event.self).filter("startDate <= %@ AND endDate > %@ ", dateProvider(), dateProvider()).count > 0
    }

    func start() {
        guard !isRunning else { return }

        os_log("start()", log: log, type: .debug)

        clearLiveSessions()

        specialEventsObserver.fetch()

        guard isWWDCWeek else {
            os_log("Not starting the live event observer because WWDC is not this week",
                   log: log,
                   type: .debug)

            isRunning = false
            return
        }

        isRunning = true

        refreshTimer = Timer.scheduledTimer(withTimeInterval: Constants.liveSessionCheckInterval, repeats: true, block: { [weak self] _ in
            self?.checkForLiveSessions()
        })
        refreshTimer?.tolerance = Constants.liveSessionCheckTolerance
    }

    /// Clears the live flag for all live sessions
    private func clearLiveSessions() {
        storage.modify(allLiveInstances.toArray()) { instances in
            instances.forEach { instance in
                instance.isCurrentlyLive = false
                instance.isForcedLive = false
            }
        }
    }

    func refresh() {
        NSObject.cancelPreviousPerformRequests(withTarget: self)
        perform(#selector(checkForLiveSessions), with: nil, afterDelay: 0)
    }

    private var allLiveInstances: Results<SessionInstance> {
        return storage.realm.objects(SessionInstance.self).filter("isCurrentlyLive == true")
    }

    @objc private func checkForLiveSessions() {
        os_log("checkForLiveSessions()", log: log, type: .debug)

        specialEventsObserver.fetch()

        syncEngine.syncLiveVideos { [weak self] in
            self?.updateLiveFlags()
        }
    }

    private func updateLiveFlags() {
        guard let startTime = Calendar.current.date(byAdding: DateComponents(minute: Constants.liveSessionStartTimeTolerance), to: dateProvider()) else {
            os_log("Could not compute a start time to check for live sessions!", log: log, type: .fault)
            return
        }

        guard let endTime = Calendar.current.date(byAdding: DateComponents(minute: Constants.liveSessionEndTimeTolerance), to: dateProvider()) else {
            os_log("Could not compute an end time to check for live sessions!", log: log, type: .fault)
            return
        }

        let previouslyLiveInstances = allLiveInstances.toArray()
        var notLiveAnymore: [SessionInstance] = []

        os_log("Looking for live instances with startTime <= %{public}@ and endTime >= %{public}@", log: log, type: .debug, String(describing: startTime), String(describing: endTime))

        let liveInstances = storage.realm.objects(SessionInstance.self).filter("startTime <= %@ AND endTime >= %@ AND SUBQUERY(session.assets, $asset, $asset.rawAssetType == %@ AND $asset.actualEndDate == nil).@count > 0", startTime, endTime, SessionAssetType.liveStreamVideo.rawValue)

{'fraction_non_alphanumeric': 0.09582375996756319, 'fraction_numerical': 0.0035139883768076766, 'mean_word_length': 2.8124678001030397, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, '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': '6164563', 'n_tokens_mistral': 2070, 'n_tokens_neox': 1942, 'n_words': 531}