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

import io.reactivex.Observable
import io.reactivex.rxkotlin.Singles.zip
import org.stepic.droid.util.concat
import org.stepik.android.domain.course_info.model.CourseInfoData
import org.stepik.android.domain.user.repository.UserRepository
import org.stepik.android.model.Course
import org.stepik.android.model.user.User
import org.stepik.android.view.video_player.model.VideoPlayerMediaData
import javax.inject.Inject

class CourseInfoInteractor
@Inject
constructor(
    private val courseObservableSource: Observable<Course>,
    private val userRepository: UserRepository
) {
    fun getCourseInfoData(): Observable<CourseInfoData> =
        courseObservableSource
            .take(1)
            .flatMap(::getCourseInfoUsers)

    private fun getCourseInfoUsers(course: Course): Observable<CourseInfoData> {
        val emptySource = Observable.just(mapToCourseInfoData(course))

        val instructorsSource = userRepository.getUsers(userIds = *course.instructors ?: longArrayOf())
        val ownerSource = userRepository.getUsers(course.owner)

        return emptySource concat
                zip(instructorsSource, ownerSource)
                    .toObservable()
                    .map { (instructors, owners) ->
                        mapToCourseInfoData(course, instructors, owners.firstOrNull())
                    }
                    .onErrorReturn {
                        mapToCourseInfoData(course, instructors = emptyList()) // fallback on network error
                    }
    }

    private fun mapToCourseInfoData(course: Course, instructors: List<User>? = null, organization: User? = null) =
        CourseInfoData(
            organization   = organization?.takeIf(User::isOrganization),
            videoMediaData = course.introVideo
                ?.takeUnless { it.urls.isNullOrEmpty() }
                ?.let { video ->
                    VideoPlayerMediaData(
                        thumbnail = course.cover,
                        title = course.title ?: "",
                        externalVideo = video
                    )
                },
            about          = course.description?.takeIf(String::isNotBlank),
            requirements   = course.requirements?.takeIf(String::isNotBlank),
            targetAudience = course.targetAudience?.takeIf(String::isNotBlank),
            timeToComplete = course.timeToComplete ?: 0,
            instructors    = (instructors ?: course.instructors?.map { null })?.takeIf { it.isNotEmpty() },
            language       = course.language,
            certificate    = course.certificate
                ?.takeIf { course.isCertificateAutoIssued || course.isCertificateIssued }
                ?.let {
                    CourseInfoData.Certificate(
                        title = it,
                        distinctionThreshold = course.certificateDistinctionThreshold,
                        regularThreshold     = course.certificateRegularThreshold
                    )
                }
        )
}<commit_msg>use same condition as in web version<commit_after>package org.stepik.android.domain.course_info.interactor

import io.reactivex.Observable
import io.reactivex.rxkotlin.Singles.zip
import org.stepic.droid.util.concat
import org.stepik.android.domain.course_info.model.CourseInfoData
import org.stepik.android.domain.user.repository.UserRepository
import org.stepik.android.model.Course
import org.stepik.android.model.user.User
import org.stepik.android.view.video_player.model.VideoPlayerMediaData
import javax.inject.Inject

class CourseInfoInteractor
@Inject
constructor(
    private val courseObservableSource: Observable<Course>,
    private val userRepository: UserRepository
) {
    fun getCourseInfoData(): Observable<CourseInfoData> =
        courseObservableSource
            .take(1)
            .flatMap(::getCourseInfoUsers)

    private fun getCourseInfoUsers(course: Course): Observable<CourseInfoData> {
        val emptySource = Observable.just(mapToCourseInfoData(course))

        val instructorsSource = userRepository.getUsers(userIds = *course.instructors ?: longArrayOf())
        val ownerSource = userRepository.getUsers(course.owner)

        return emptySource concat
                zip(instructorsSource, ownerSource)
                    .toObservable()
                    .map { (instructors, owners) ->
                        mapToCourseInfoData(course, instructors, owners.firstOrNull())
                    }
                    .onErrorReturn {
                        mapToCourseInfoData(course, instructors = emptyList()) // fallback on network error
                    }
    }

    private fun mapToCourseInfoData(course: Course, instructors: List<User>? = null, organization: User? = null) =
        CourseInfoData(
            organization   = organization?.takeIf(User::isOrganization),
            videoMediaData = course.introVideo
                ?.takeUnless { it.urls.isNullOrEmpty() }
                ?.let { video ->
                    VideoPlayerMediaData(
                        thumbnail = course.cover,
                        title = course.title ?: "",
                        externalVideo = video
                    )
                },
            about          = course.description?.takeIf(String::isNotBlank),
            requirements   = course.requirements?.takeIf(String::isNotBlank),
            targetAudience = course.targetAudience?.takeIf(String::isNotBlank),
            timeToComplete = course.timeToComplete ?: 0,
            instructors    = (instructors ?: course.instructors?.map { null })?.takeIf { it.isNotEmpty() },
            language       = course.language,
            certificate    = course.certificate
                ?.takeIf {
                    val hasText = it.isNotEmpty()
                    val anyCertificateThreshold = course.certificateRegularThreshold > 0 || course.certificateDistinctionThreshold > 0
                    anyCertificateThreshold && (hasText || (course.isCertificateAutoIssued && course.isCertificateIssued))
                }
                ?.let {
                    CourseInfoData.Certificate(
                        title = it,
                        distinctionThreshold = course.certificateDistinctionThreshold,
                        regularThreshold     = course.certificateRegularThreshold
                    )
                }
        )
}
{'fraction_non_alphanumeric': 0.08467492260061919, 'fraction_numerical': 0.0009287925696594427, 'mean_word_length': 2.062085308056872, 'pattern_counts': {'":': 0, '<': 11, '<?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': '6276953', 'n_tokens_mistral': 1639, 'n_tokens_neox': 1540, 'n_words': 277}