<commit_before>package org.stepik.android.presentation.course

import io.reactivex.Maybe
import io.reactivex.Observable
import io.reactivex.Scheduler
import io.reactivex.Single
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import io.reactivex.rxkotlin.subscribeBy
import org.stepic.droid.analytic.Analytic
import org.stepic.droid.di.qualifiers.BackgroundScheduler
import org.stepic.droid.di.qualifiers.CourseId
import org.stepic.droid.di.qualifiers.MainScheduler
import ru.nobird.android.domain.rx.emptyOnErrorStub
import org.stepic.droid.util.plus
import org.stepik.android.domain.course.analytic.CoursePreviewScreenOpenedAnalyticEvent
import org.stepik.android.domain.course.analytic.CourseViewSource
import org.stepik.android.domain.course.interactor.CourseEnrollmentInteractor
import org.stepik.android.domain.course.interactor.CourseIndexingInteractor
import org.stepik.android.domain.course.interactor.CourseInteractor
import org.stepik.android.domain.course.model.CourseHeaderData
import org.stepik.android.domain.course.model.EnrollmentState
import org.stepik.android.domain.notification.interactor.CourseNotificationInteractor
import org.stepik.android.domain.solutions.interactor.SolutionsInteractor
import org.stepik.android.domain.solutions.model.SolutionItem
import org.stepik.android.domain.user_courses.interactor.UserCoursesInteractor
import org.stepik.android.domain.user_courses.model.UserCourse
import org.stepik.android.domain.user_courses.model.UserCourseHeader
import org.stepik.android.model.Course
import org.stepik.android.presentation.course.mapper.toEnrollmentError
import org.stepik.android.presentation.course.model.EnrollmentError
import org.stepik.android.presentation.course_continue.delegate.CourseContinuePresenterDelegate
import org.stepik.android.presentation.course_continue.delegate.CourseContinuePresenterDelegateImpl
import org.stepik.android.presentation.course_continue.model.CourseContinueInteractionSource
import org.stepik.android.presentation.user_courses.model.UserCourseAction
import org.stepik.android.view.injection.course.EnrollmentCourseUpdates
import org.stepik.android.view.injection.course_list.UserCoursesOperationBus
import org.stepik.android.view.injection.solutions.SolutionsBus
import org.stepik.android.view.injection.solutions.SolutionsSentBus
import ru.nobird.android.presentation.base.PresenterBase
import ru.nobird.android.presentation.base.PresenterViewContainer
import ru.nobird.android.presentation.base.delegate.PresenterDelegate
import javax.inject.Inject

class CoursePresenter
@Inject
constructor(
    @CourseId
    private val courseId: Long,

    viewContainer: PresenterViewContainer<CourseView>,

    private val courseContinuePresenterDelegateImpl: CourseContinuePresenterDelegateImpl,

    private val courseInteractor: CourseInteractor,
//    private val courseBillingInteractor: CourseBillingInteractor,
    private val courseEnrollmentInteractor: CourseEnrollmentInteractor,
    private val courseIndexingInteractor: CourseIndexingInteractor,
    private val solutionsInteractor: SolutionsInteractor,
    private val userCoursesInteractor: UserCoursesInteractor,

    private val courseNotificationInteractor: CourseNotificationInteractor,

    @EnrollmentCourseUpdates
    private val enrollmentUpdatesObservable: Observable<Course>,

    @SolutionsBus
    private val solutionsObservable: Observable<Unit>,

    @SolutionsSentBus
    private val solutionsSentObservable: Observable<Unit>,

    @UserCoursesOperationBus
    private val userCourseOperationObservable: Observable<UserCourse>,

    @BackgroundScheduler
    private val backgroundScheduler: Scheduler,
    @MainScheduler
    private val mainScheduler: Scheduler,
    private val analytic: Analytic
) : PresenterBase<CourseView>(viewContainer), CourseContinuePresenterDelegate by courseContinuePresenterDelegateImpl {
    private var state: CourseView.State = CourseView.State.Idle
        set(value) {
            field = value
            view?.setState(value)
            startIndexing()
        }

//    private var uiCheckout: UiCheckout? = null

    private var isCoursePreviewLogged = false
    private var isNeedCheckCourseEnrollment = false
    private lateinit var viewSource: CourseViewSource

    override val delegates: List<PresenterDelegate<in CourseView>> =
        listOf(courseContinuePresenterDelegateImpl)

    private val userCourseDisposable = CompositeDisposable()

    init {
        compositeDisposable += userCourseDisposable
        subscriberForEnrollmentUpdates()
        subscribeForLocalSubmissionsUpdates()
        subscribeForUserCoursesUpdates()
    }

    override fun attachView(view: CourseView) {
        super.attachView(view)
        view.setState(state)
        startIndexing()

//        uiCheckout = view
//            .createUiCheckout()
//            .also(UiCheckout::start)
    }

    override fun detachView(view: CourseView) {
        super.detachView(view)
        endIndexing()

//        uiCheckout?.let(UiCheckout::stop)
//        uiCheckout = null
    }

    /**
     * Data initialization variants
     */
    fun onCourseId(courseId: Long, viewSource: CourseViewSource, forceUpdate: Boolean = false) {
        val courseIdToPass = (state as? CourseView.State.CourseLoaded)
            ?.courseHeaderData
            ?.courseId
            ?: courseId
        observeCourseData(courseInteractor.getCourseHeaderData(courseIdToPass, canUseCache = !forceUpdate), viewSource, forceUpdate)
    }

    fun onCourse(course: Course, viewSource: CourseViewSource, forceUpdate: Boolean = false) {
        val courseToPass = (state as? CourseView.State.CourseLoaded)
            ?.courseHeaderData
            ?.course
            ?: course
        observeCourseData(courseInteractor.getCourseHeaderData(courseToPass, canUseCache = !forceUpdate), viewSource, forceUpdate)<commit_msg>Fix courseHeaderDataSource fallback<commit_after>package org.stepik.android.presentation.course

import io.reactivex.Maybe
import io.reactivex.Observable
import io.reactivex.Scheduler
import io.reactivex.Single
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import io.reactivex.rxkotlin.subscribeBy
import org.stepic.droid.analytic.Analytic
import org.stepic.droid.di.qualifiers.BackgroundScheduler
import org.stepic.droid.di.qualifiers.CourseId
import org.stepic.droid.di.qualifiers.MainScheduler
import ru.nobird.android.domain.rx.emptyOnErrorStub
import org.stepic.droid.util.plus
import org.stepik.android.domain.course.analytic.CoursePreviewScreenOpenedAnalyticEvent
import org.stepik.android.domain.course.analytic.CourseViewSource
import org.stepik.android.domain.course.interactor.CourseEnrollmentInteractor
import org.stepik.android.domain.course.interactor.CourseIndexingInteractor
import org.stepik.android.domain.course.interactor.CourseInteractor
import org.stepik.android.domain.course.model.CourseHeaderData
import org.stepik.android.domain.course.model.EnrollmentState
import org.stepik.android.domain.notification.interactor.CourseNotificationInteractor
import org.stepik.android.domain.solutions.interactor.SolutionsInteractor
import org.stepik.android.domain.solutions.model.SolutionItem
import org.stepik.android.domain.user_courses.interactor.UserCoursesInteractor
import org.stepik.android.domain.user_courses.model.UserCourse
import org.stepik.android.domain.user_courses.model.UserCourseHeader
import org.stepik.android.model.Course
import org.stepik.android.presentation.course.mapper.toEnrollmentError
import org.stepik.android.presentation.course.model.EnrollmentError
import org.stepik.android.presentation.course_continue.delegate.CourseContinuePresenterDelegate
import org.stepik.android.presentation.course_continue.delegate.CourseContinuePresenterDelegateImpl
import org.stepik.android.presentation.course_continue.model.CourseContinueInteractionSource
import org.stepik.android.presentation.user_courses.model.UserCourseAction
import org.stepik.android.view.injection.course.EnrollmentCourseUpdates
import org.stepik.android.view.injection.course_list.UserCoursesOperationBus
import org.stepik.android.view.injection.solutions.SolutionsBus
import org.stepik.android.view.injection.solutions.SolutionsSentBus
import ru.nobird.android.presentation.base.PresenterBase
import ru.nobird.android.presentation.base.PresenterViewContainer
import ru.nobird.android.presentation.base.delegate.PresenterDelegate
import javax.inject.Inject

class CoursePresenter
@Inject
constructor(
    @CourseId
    private val courseId: Long,

    viewContainer: PresenterViewContainer<CourseView>,

    private val courseContinuePresenterDelegateImpl: CourseContinuePresenterDelegateImpl,

    private val courseInteractor: CourseInteractor,
//    private val courseBillingInteractor: CourseBillingInteractor,
    private val courseEnrollmentInteractor: CourseEnrollmentInteractor,
    private val courseIndexingInteractor: CourseIndexingInteractor,
    private val solutionsInteractor: SolutionsInteractor,
    private val userCoursesInteractor: UserCoursesInteractor,

    private val courseNotificationInteractor: CourseNotificationInteractor,

    @EnrollmentCourseUpdates
    private val enrollmentUpdatesObservable: Observable<Course>,

    @SolutionsBus
    private val solutionsObservable: Observable<Unit>,

    @SolutionsSentBus
    private val solutionsSentObservable: Observable<Unit>,

    @UserCoursesOperationBus
    private val userCourseOperationObservable: Observable<UserCourse>,

    @BackgroundScheduler
    private val backgroundScheduler: Scheduler,
    @MainScheduler
    private val mainScheduler: Scheduler,
    private val analytic: Analytic
) : PresenterBase<CourseView>(viewContainer), CourseContinuePresenterDelegate by courseContinuePresenterDelegateImpl {
    private var state: CourseView.State = CourseView.State.Idle
        set(value) {
            field = value
            view?.setState(value)
            startIndexing()
        }

//    private var uiCheckout: UiCheckout? = null

    private var isCoursePreviewLogged = false
    private var isNeedCheckCourseEnrollment = false
    private lateinit var viewSource: CourseViewSource

    override val delegates: List<PresenterDelegate<in CourseView>> =
        listOf(courseContinuePresenterDelegateImpl)

    private val userCourseDisposable = CompositeDisposable()

    init {
        compositeDisposable += userCourseDisposable
        subscriberForEnrollmentUpdates()
        subscribeForLocalSubmissionsUpdates()
        subscribeForUserCoursesUpdates()
    }

    override fun attachView(view: CourseView) {
        super.attachView(view)
        view.setState(state)
        startIndexing()

//        uiCheckout = view
//            .createUiCheckout()
//            .also(UiCheckout::start)
    }

    override fun detachView(view: CourseView) {
        super.detachView(view)
        endIndexing()

//        uiCheckout?.let(UiCheckout::stop)
//        uiCheckout = null
    }

    /**
     * Data initialization variants
     */
    fun onCourseId(courseId: Long, viewSource: CourseViewSource, forceUpdate: Boolean = false) {
        val courseHeaderDataSource = (state as? CourseView.State.CourseLoaded)
            ?.courseHeaderData
            ?.course
            ?.let { courseInteractor.getCourseHeaderData(it, canUseCache = !forceUpdate) }
            ?: courseInteractor.getCourseHeaderData(courseId, canUseCache = !forceUpdate)
        observeCourseData(courseHeaderDataSource, viewSource, forceUpdate)
    }

    fun onCourse(course: Course, viewSource: CourseViewSource, forceUpdate: Boolean = false) {
        val courseToPass = (state as? CourseView.State.CourseLoaded)
            ?.courseHeaderData
            ?.course
            ?: course
        observeCourseData(courseInteractor.getCourseHeaderData(courseToPass, canUseCache = !forceUpdate), viewSource, forceUpdate)
{'fraction_non_alphanumeric': 0.07390686397458407, 'fraction_numerical': 0.0, 'mean_word_length': 4.723444976076555, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, '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': '141632', 'n_tokens_mistral': 3368, 'n_tokens_neox': 3181, 'n_words': 553}