content: /*
   * Copyright 2016, The Android Open Source Project
   *
   * 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 <%= appPackage %>.statistics;
  
  import android.support.annotation.NonNull;
  import android.support.v4.util.Pair;
  
  import <%= appPackage %>.data.Task;
  import <%= appPackage %>.data.source.TasksRepository;
  import <%= appPackage %>.util.EspressoIdlingResource;
  import <%= appPackage %>.util.schedulers.BaseSchedulerProvider;
  
  import rx.Observable;
  import rx.Subscription;
  import rx.subscriptions.CompositeSubscription;
  
  import static com.google.common.base.Preconditions.checkNotNull;
  
  /**
   * Listens to user actions from the UI ({@link StatisticsFragment}), retrieves the data and updates
   * the UI as required.
   */
  public class StatisticsPresenter implements StatisticsContract.Presenter {
  
      @NonNull
      private final TasksRepository mTasksRepository;
  
      @NonNull
      private final StatisticsContract.View mStatisticsView;
  
      @NonNull
      private final BaseSchedulerProvider mSchedulerProvider;
  
      @NonNull
      private CompositeSubscription mSubscriptions;
  
      public StatisticsPresenter(@NonNull TasksRepository tasksRepository,
                                 @NonNull StatisticsContract.View statisticsView,
                                 @NonNull BaseSchedulerProvider schedulerProvider) {
          mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null");
          mStatisticsView = checkNotNull(statisticsView, "statisticsView cannot be null!");
          mSchedulerProvider = checkNotNull(schedulerProvider, "schedulerProvider cannot be null");
  
          mSubscriptions = new CompositeSubscription();
          mStatisticsView.setPresenter(this);
      }
  
      @Override
      public void subscribe() {
          loadStatistics();
      }
  
      @Override
      public void unsubscribe() {
          mSubscriptions.clear();
      }
  
      private void loadStatistics() {
          mStatisticsView.setProgressIndicator(true);
  
          // The network request might be handled in a different thread so make sure Espresso knows
          // that the app is busy until the response is handled.
          EspressoIdlingResource.increment(); // App is busy until further notice
  
          Observable<Task> tasks = mTasksRepository
                  .getTasks()
                  .flatMap(Observable::from);
          Observable<Integer> completedTasks = tasks.filter(Task::isCompleted).count();
          Observable<Integer> activeTasks = tasks.filter(Task::isActive).count();
          Subscription subscription = Observable
                  .zip(completedTasks, activeTasks, (completed, active) -> Pair.create(active, completed))
                  .subscribeOn(mSchedulerProvider.computation())
                  .observeOn(mSchedulerProvider.ui())
                  .doOnTerminate(() -> {
                      if (!EspressoIdlingResource.getIdlingResource().isIdleNow()) {
                          EspressoIdlingResource.decrement(); // Set app as idle.
                      }
                  })
                  .subscribe(
                          // onNext
                          stats -> mStatisticsView.showStatistics(stats.first, stats.second),
                          // onError
                          throwable -> mStatisticsView.showLoadingStatisticsError(),
                          // onCompleted
                          () -> mStatisticsView.setProgressIndicator(false));
          mSubscriptions.add(subscription);
      }
  }
  