<commit_before>/*
 * Copyright 2018 Google, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package app.tivi.showdetails.details

import android.arch.lifecycle.MutableLiveData
import app.tivi.SharedElementHelper
import app.tivi.actions.ShowTasks
import app.tivi.interactors.SyncShowWatchedEpisodesInteractor
import app.tivi.data.daos.FollowedShowsDao
import app.tivi.data.entities.Episode
import app.tivi.data.entities.TiviShow
import app.tivi.datasources.trakt.RelatedShowsDataSource
import app.tivi.datasources.trakt.ShowDetailsDataSource
import app.tivi.datasources.trakt.ShowSeasonsDataSource
import app.tivi.showdetails.ShowDetailsNavigator
import app.tivi.tmdb.TmdbManager
import app.tivi.util.AppRxSchedulers
import app.tivi.util.Logger
import app.tivi.util.TiviViewModel
import io.reactivex.rxkotlin.Flowables
import io.reactivex.rxkotlin.plusAssign
import javax.inject.Inject

class ShowDetailsFragmentViewModel @Inject constructor(
    private val schedulers: AppRxSchedulers,
    private val showCall: ShowDetailsDataSource,
    private val relatedShows: RelatedShowsDataSource,
    private val seasonsCall: ShowSeasonsDataSource,
    private val showWatchedEpisodesCall: SyncShowWatchedEpisodesInteractor,
    private val tmdbManager: TmdbManager,
    private val showTasks: ShowTasks,
    private val followedShowsDao: FollowedShowsDao,
    private val logger: Logger
) : TiviViewModel() {

    var showId: Long? = null
        set(value) {
            if (field != value) {
                field = value
                if (value != null) {
                    setupLiveData()
                    refresh()
                } else {
                    data.value = null
                }
            }
        }

    val data = MutableLiveData<ShowDetailsViewState>()

    private fun refresh() {
        showId?.let { id ->
            launchWithParent {
                showCall.refresh(id)
            }
            launchWithParent {
                relatedShows.refresh(id)
            }
            launchWithParent {
                if (followedShowsDao.entryCountWithShowId(id) > 0) {
                    showWatchedEpisodesCall.invoke(id)
                }
            }
        }
    }

    private fun setupLiveData() {
        showId?.let { id ->
            disposables += followedShowsDao.entryCountWithShowIdFlowable(id)
                    .subscribeOn(schedulers.database)
                    .flatMap {
                        if (it > 0) {
                            // Followed show
                            Flowables.combineLatest(
                                    showCall.data(id),
                                    relatedShows.data(id),
                                    seasonsCall.data(id),
                                    tmdbManager.imageProvider,
                                    ::FollowedShowDetailsViewState)
                        } else {
                            // Not followed
                            Flowables.combineLatest(
                                    showCall.data(id),
                                    relatedShows.data(id),
                                    tmdbManager.imageProvider,
                                    ::NotFollowedShowDetailsViewState)
                        }
                    }
                    .observeOn(schedulers.main)
                    .subscribe(data::setValue, logger::e)
        }
    }

    fun addToMyShows() {
        showId?.let {
            showTasks.followShow(it)
        }
    }

    fun removeFromMyShows() {
        showId?.let {
            showTasks.unfollowShow(it)
        }
    }

    fun onRelatedShowClicked(
        showDetailsNavigator: ShowDetailsNavigator,
        show: TiviShow,
        sharedElementHelper: SharedElementHelper? = null
    ) = showDetailsNavigator.showShowDetails(show, sharedElementHelper)

    fun onRelatedShowClicked(
        showDetailsNavigator: ShowDetailsNavigator,
        episode: Episode
    ) = showDetailsNavigator.showEpisodeDetails(episode)
}<commit_msg>Move Show Details Fragment VM to interactors<commit_after>/*
 * Copyright 2018 Google, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package app.tivi.showdetails.details

import android.arch.lifecycle.MutableLiveData
import app.tivi.SharedElementHelper
import app.tivi.data.daos.FollowedShowsDao
import app.tivi.data.entities.Episode
import app.tivi.data.entities.TiviShow
import app.tivi.datasources.trakt.RelatedShowsDataSource
import app.tivi.datasources.trakt.ShowDetailsDataSource
import app.tivi.datasources.trakt.ShowSeasonsDataSource
import app.tivi.interactors.FollowShowInteractor
import app.tivi.interactors.SyncShowWatchedEpisodesInteractor
import app.tivi.interactors.UnfollowShowInteractor
import app.tivi.showdetails.ShowDetailsNavigator
import app.tivi.tmdb.TmdbManager
import app.tivi.util.AppRxSchedulers
import app.tivi.util.Logger
import app.tivi.util.TiviViewModel
import io.reactivex.rxkotlin.Flowables
import io.reactivex.rxkotlin.plusAssign
import javax.inject.Inject

class ShowDetailsFragmentViewModel @Inject constructor(
    private val schedulers: AppRxSchedulers,
    private val showCall: ShowDetailsDataSource,
    private val relatedShows: RelatedShowsDataSource,
    private val seasonsCall: ShowSeasonsDataSource,
    private val showWatchedEpisodesCall: SyncShowWatchedEpisodesInteractor,
    private val tmdbManager: TmdbManager,
    private val followShowCall: FollowShowInteractor,
    private val unfollowShowCall: UnfollowShowInteractor,
    private val followedShowsDao: FollowedShowsDao,
    private val logger: Logger
) : TiviViewModel() {

    var showId: Long? = null
        set(value) {
            if (field != value) {
                field = value
                if (value != null) {
                    setupLiveData()
                    refresh()
                } else {
                    data.value = null
                }
            }
        }

    val data = MutableLiveData<ShowDetailsViewState>()

    private fun refresh() {
        showId?.let { id ->
            launchWithParent {
                showCall.refresh(id)
            }
            launchWithParent {
                relatedShows.refresh(id)
            }
            launchWithParent {
                if (followedShowsDao.entryCountWithShowId(id) > 0) {
                    showWatchedEpisodesCall.invoke(id)
                }
            }
        }
    }

    private fun setupLiveData() {
        showId?.let { id ->
            disposables += followedShowsDao.entryCountWithShowIdFlowable(id)
                    .subscribeOn(schedulers.database)
                    .flatMap {
                        if (it > 0) {
                            // Followed show
                            Flowables.combineLatest(
                                    showCall.data(id),
                                    relatedShows.data(id),
                                    seasonsCall.data(id),
                                    tmdbManager.imageProvider,
                                    ::FollowedShowDetailsViewState)
                        } else {
                            // Not followed
                            Flowables.combineLatest(
                                    showCall.data(id),
                                    relatedShows.data(id),
                                    tmdbManager.imageProvider,
                                    ::NotFollowedShowDetailsViewState)
                        }
                    }
                    .observeOn(schedulers.main)
                    .subscribe(data::setValue, logger::e)
        }
    }

    fun addToMyShows() {
        showId?.let { id ->
            launchWithParent {
                followShowCall.invoke(id)
                showWatchedEpisodesCall.invoke(id)
            }
        }
    }

    fun removeFromMyShows() {
        showId?.let { id ->
            launchWithParent {
                unfollowShowCall.invoke(id)
            }
        }
    }

    fun onRelatedShowClicked(
        showDetailsNavigator: ShowDetailsNavigator,
        show: TiviShow,
        sharedElementHelper: SharedElementHelper? = null
    ) = showDetailsNavigator.showShowDetails(show, sharedElementHelper)

    fun onRelatedShowClicked(
        showDetailsNavigator: ShowDetailsNavigator,
        episode: Episode
    ) = showDetailsNavigator.showEpisodeDetails(episode)
}
{'fraction_non_alphanumeric': 0.06973795435333897, 'fraction_numerical': 0.002113271344040575, 'mean_word_length': 1.8169642857142858, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 35, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1568454', 'n_tokens_mistral': 2506, 'n_tokens_neox': 2398, 'n_words': 525}