<commit_before>package org.stepik.android.domain.course_content.interactor

import com.google.firebase.perf.FirebasePerformance
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.rxkotlin.Observables
import io.reactivex.rxkotlin.toObservable
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.PublishSubject
import org.stepic.droid.analytic.AmplitudeAnalytic
import org.stepic.droid.analytic.Analytic
import org.stepic.droid.util.mapToLongArray
import org.stepic.droid.util.plus
import org.stepik.android.domain.base.DataSourceType
import org.stepik.android.domain.lesson.repository.LessonRepository
import org.stepik.android.domain.progress.mapper.getProgresses
import org.stepik.android.domain.progress.repository.ProgressRepository
import org.stepik.android.domain.section.repository.SectionRepository
import org.stepik.android.domain.unit.repository.UnitRepository
import org.stepik.android.model.Course
import org.stepik.android.model.Section
import org.stepik.android.model.Unit
import org.stepik.android.presentation.course_content.mapper.CourseContentItemMapper
import org.stepik.android.view.course_content.model.CourseContentItem
import javax.inject.Inject

class CourseContentInteractor
@Inject
constructor(
    private val courseObservableSource: Observable<Course>,
    private val sectionRepository: SectionRepository,
    private val unitRepository: UnitRepository,
    private val lessonRepository: LessonRepository,
    private val progressRepository: ProgressRepository,

    private val courseContentItemMapper: CourseContentItemMapper
) {
    companion object {
        private const val UNITS_CHUNK_SIZE = 10
    }

    fun getCourseContent(shouldSkipStoredValue: Boolean = false): Observable<Pair<Course, List<CourseContentItem>>> =
        courseObservableSource
            .skip(if (shouldSkipStoredValue) 1 else 0)
            .switchMap { course ->
                // todo: determine should we update from cache or not
                val shouldUseCache = !shouldSkipStoredValue
                val contentObservable =
                    if (shouldUseCache) {
                        val cacheSource = getContent(course, emptyList(), DataSourceType.CACHE)
                            .share()

                        val remoteSource = cacheSource
                            .lastOrError()
                            .flatMapObservable { (_, items) ->
                                getContent(course, items, DataSourceType.REMOTE)
                            }

                        Observable.concat(cacheSource, remoteSource)
                    } else {
                        getContent(course, emptyList(), DataSourceType.REMOTE)<commit_msg>test impl<commit_after>package org.stepik.android.domain.course_content.interactor

import com.google.firebase.perf.FirebasePerformance
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.rxkotlin.Observables
import io.reactivex.rxkotlin.toObservable
import io.reactivex.rxkotlin.zipWith
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.PublishSubject
import org.stepic.droid.analytic.AmplitudeAnalytic
import org.stepic.droid.analytic.Analytic
import org.stepic.droid.util.mapToLongArray
import org.stepic.droid.util.plus
import org.stepik.android.domain.base.DataSourceType
import org.stepik.android.domain.lesson.repository.LessonRepository
import org.stepik.android.domain.progress.mapper.getProgresses
import org.stepik.android.domain.progress.repository.ProgressRepository
import org.stepik.android.domain.section.repository.SectionRepository
import org.stepik.android.domain.unit.repository.UnitRepository
import org.stepik.android.model.Course
import org.stepik.android.model.Section
import org.stepik.android.model.Unit
import org.stepik.android.presentation.course_content.mapper.CourseContentItemMapper
import org.stepik.android.view.course_content.model.CourseContentItem
import javax.inject.Inject

class CourseContentInteractor
@Inject
constructor(
    private val courseObservableSource: Observable<Course>,
    private val sectionRepository: SectionRepository,
    private val unitRepository: UnitRepository,
    private val lessonRepository: LessonRepository,
    private val progressRepository: ProgressRepository,

    private val courseContentItemMapper: CourseContentItemMapper
) {
    companion object {
        private const val UNITS_CHUNK_SIZE = 10
    }

    fun getCourseContent(shouldSkipStoredValue: Boolean = false): Observable<Pair<Course, List<CourseContentItem>>> =
        courseObservableSource
            .zipWith(Observable.range(0, Int.MAX_VALUE))
            .skip(if (shouldSkipStoredValue) 1 else 0)
            .switchMap { (course, count) ->
                val shouldUseCache = count == 0
                val contentObservable =
                    if (shouldUseCache) {
                        val cacheSource = getContent(course, emptyList(), DataSourceType.CACHE)
                            .share()

                        val remoteSource = cacheSource
                            .lastOrError()
                            .flatMapObservable { (_, items) ->
                                getContent(course, items, DataSourceType.REMOTE)
                            }

                        Observable.concat(cacheSource, remoteSource)
                    } else {
                        getContent(course, emptyList(), DataSourceType.REMOTE)
{'fraction_non_alphanumeric': 0.07412817235712982, 'fraction_numerical': 0.0018258170531312763, 'mean_word_length': 3.0368459837877673, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, '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': '5111946', 'n_tokens_mistral': 1470, 'n_tokens_neox': 1386, 'n_words': 265}