<commit_before>//
//  Subject.swift
//  WaniKaniKit
//
//  Copyright © 2017 <NAME>. All rights reserved.
//

public enum SubjectType: String, Codable {
    case radical
    case kanji
    case vocabulary
}

public extension SubjectType {
    var backgroundColor: UIColor {
        switch self {
        case .radical:
            return .waniKaniRadical
        case .kanji:
            return .waniKaniKanji
        case .vocabulary:
            return .waniKaniVocabulary
        }
    }
}

public protocol SubjectImage {
    var url: URL { get }
    var contentType: String { get }
}

public protocol Subject {
    var subjectType: SubjectType { get }
    var level: Int { get }
    var slug: String { get }
    var documentURL: URL { get }
    var meanings: [Meaning] { get }
    var readings: [Reading] { get }
    var componentSubjectIDs: [Int] { get }
    var lessonPosition: Int { get }
}

extension Subject {
    public func earliestGuruDate(assignment: Assignment?, getAssignmentForSubjectID: (Int) -> Assignment?) -> Date? {
        if assignment?.isPassed == true {
            return assignment?.passedAt ?? Date.distantPast
        }
        
        let pendingSubjectAssignments = componentSubjectIDs.map({ componentSubjectID in getAssignmentForSubjectID(componentSubjectID) })
            .filter({ assignment in assignment?.isPassed != true })
        
        let unlockDateForLockedItems: Date?
        if pendingSubjectAssignments.isEmpty {
            unlockDateForLockedItems = Calendar.current.startOfHour(for: Date())
        } else {
            let guruDates = pendingSubjectAssignments.map({ assignment in assignment?.guruDate(level: level) })
            unlockDateForLockedItems = guruDates.lazy.filter({ $0 == nil }).isEmpty ? guruDates.lazy.compactMap({ $0 }).max() : nil
        }
        
        let guruDate: Date?
        if let assignment = assignment {
            guruDate = assignment.guruDate(level: level)
        } else if let unlockDateForLockedItems = unlockDateForLockedItems {
            guruDate = Assignment.earliestDate(from: unlockDateForLockedItems,<commit_msg>Fix guru time calculation for locked subjects with initiate assignments<commit_after>//
//  Subject.swift
//  WaniKaniKit
//
//  Copyright © 2017 <NAME>. All rights reserved.
//

public enum SubjectType: String, Codable {
    case radical
    case kanji
    case vocabulary
}

public extension SubjectType {
    var backgroundColor: UIColor {
        switch self {
        case .radical:
            return .waniKaniRadical
        case .kanji:
            return .waniKaniKanji
        case .vocabulary:
            return .waniKaniVocabulary
        }
    }
}

public protocol SubjectImage {
    var url: URL { get }
    var contentType: String { get }
}

public protocol Subject {
    var subjectType: SubjectType { get }
    var level: Int { get }
    var slug: String { get }
    var documentURL: URL { get }
    var meanings: [Meaning] { get }
    var readings: [Reading] { get }
    var componentSubjectIDs: [Int] { get }
    var lessonPosition: Int { get }
}

extension Subject {
    public func earliestGuruDate(assignment: Assignment?, getAssignmentForSubjectID: (Int) -> Assignment?) -> Date? {
        if assignment?.isPassed == true {
            return assignment?.passedAt ?? Date.distantPast
        }
        
        let pendingSubjectAssignments = componentSubjectIDs.map({ componentSubjectID in getAssignmentForSubjectID(componentSubjectID) })
            .filter({ assignment in assignment?.isPassed != true })
        
        let unlockDateForLockedItems: Date?
        if pendingSubjectAssignments.isEmpty {
            unlockDateForLockedItems = Calendar.current.startOfHour(for: Date())
        } else {
            let guruDates = pendingSubjectAssignments.map({ assignment in assignment?.guruDate(level: level) })
            unlockDateForLockedItems = guruDates.lazy.filter({ $0 == nil }).isEmpty ? guruDates.lazy.compactMap({ $0 }).max() : nil
        }
        
        let guruDate: Date?
        if let assignment = assignment, assignment.srsStage > 0 {
            guruDate = assignment.guruDate(level: level)
        } else if let unlockDateForLockedItems = unlockDateForLockedItems {
            guruDate = Assignment.earliestDate(from: unlockDateForLockedItems,
{'fraction_non_alphanumeric': 0.08926501275214468, 'fraction_numerical': 0.0030141432877347552, 'mean_word_length': 2.530278232405892, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 10, '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': '221253', 'n_tokens_mistral': 1207, 'n_tokens_neox': 1190, 'n_words': 324}