/*
 * Copyright 2018 Google LLC
 *
 * 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
 *
 *     https://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 com.google.android.gnd.ui.home.featuresheet;

import static java8.util.stream.StreamSupport.stream;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.google.android.gnd.repository.DataRepository;
import com.google.android.gnd.ui.common.AbstractViewModel;
import com.google.android.gnd.vo.Feature;
import com.google.android.gnd.vo.Form;
import com.google.android.gnd.vo.Project;
import com.google.android.gnd.vo.Record;
import java.util.Collections;
import java.util.List;
import java8.util.Optional;
import java8.util.stream.Collectors;
import javax.inject.Inject;

// TODO: Roll up into parent viewmodel. Simplify VMs overall.
public class RecordListViewModel extends AbstractViewModel {
  private static final String TAG = RecordListViewModel.class.getSimpleName();
  private final DataRepository dataRepository;
  private MutableLiveData<List<Record>> recordSummaries;

  @Inject
  public RecordListViewModel(DataRepository dataRepository) {
    this.dataRepository = dataRepository;
    recordSummaries = new MutableLiveData<>();
  }

  public LiveData<List<Record>> getRecordSummaries() {
    return recordSummaries;
  }

  public void clearRecords() {
    recordSummaries.setValue(Collections.emptyList());
  }

  public void loadRecordSummaries(Feature feature, Form form) {
    loadRecords(
        feature.getProject(), feature.getFeatureType().getId(), form.getId(), feature.getId());
  }

  private void loadRecords(Project project, String featureTypeId, String formId, String featureId) {
    Optional<Form> form = project.getFeatureType(featureTypeId).flatMap(pt -> pt.getForm(formId));
    if (!form.isPresent()) {
      // TODO: Show error.
      return;
    }
    // TODO: Use project id instead of object.
    // TODO(#24): Fix leaky subscriptions!
    disposeOnClear(
        dataRepository
            .getRecordSummaries(project.getId(), featureId)
            .subscribe(
                // TODO: Only fetch records w/current formId.
                records ->
                    recordSummaries.setValue(
                        stream(records)
                            .filter(record -> record.getForm().getId().equals(formId))
                            .collect(Collectors.toList()))));
  }
}

@@ -698,16 +698,48 @@
 tream;%0A%0A
+import androidx.core.util.Pair;%0A
 import a
@@ -762,24 +762,24 @@
 e.LiveData;%0A
-
 import andro
@@ -1142,16 +1142,147 @@
 l.List;%0A
+import java.util.Map;%0A%0Aimport io.reactivex.Flowable;%0Aimport io.reactivex.Single;%0Aimport io.reactivex.processors.BehaviorProcessor;%0A
 import j
@@ -1490,16 +1490,309 @@
 Model %7B%0A
+%0A  class ArgumentWrapper %7B%0A    public Project project;%0A    public String featureId;%0A    public String formId;%0A%0A    public ArgumentWrapper(Project project, String featureId, String formId) %7B%0A      this.project = project;%0A      this.featureId = featureId;%0A      this.formId = formId;%0A    %7D%0A  %7D%0A%0A
   privat
@@ -1965,16 +1965,80 @@
 mmaries;
+%0A  private BehaviorProcessor%3CArgumentWrapper%3E argumentProcessor;
 %0A%0A  @Inj
@@ -2192,16 +2192,719 @@
 ta%3C%3E();%0A
+    argumentProcessor = BehaviorProcessor.create();%0A%0A    Flowable%3CPair%3CList%3CRecord%3E, String%3E%3E recordsWithFormContext =%0A        argumentProcessor.flatMap(%0A            args -%3E%0A                dataRepository%0A                    .getRecordSummaries(args.project.getId(), args.featureId)%0A                    .toFlowable()%0A                    .map(records -%3E Pair.create(records, args.formId)));%0A%0A    disposeOnClear(%0A        recordsWithFormContext.subscribe(%0A            pairs -%3E%0A                recordSummaries.setValue(%0A                    stream(pairs.first)%0A                        .filter(record -%3E record.getForm().getId().equals(pairs.second))%0A                        .collect(Collectors.toList()))));%0A
   %7D%0A%0A  p
@@ -3635,451 +3635,79 @@
     
-disposeOnClear(%0A        dataRepository%0A            .getRecordSummaries(project.getId(), featureId)%0A            .subscribe(%0A                // TODO: Only fetch records w/current formId.%0A                records -%3E%0A                    recordSummaries.setValue(%0A                        stream(records)%0A                            .filter(record -%3E record.getForm().getId().equals(formId))%0A                            .collect(Collectors.toList()))
+argumentProcessor.onNext(new ArgumentWrapper(project, featureId, formId
 ));%0A

Fix leaky subscription in RecordListViewModel.