/*
 * Copyright 2016 Peter Kenji Yamanaka
 *
 * 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 com.pyamsoft.padlock.dagger.purge;

import android.support.annotation.NonNull;
import com.pyamsoft.padlock.app.purge.PurgePresenter;
import com.pyamsoft.padlock.model.sql.PadLockEntry;
import com.pyamsoft.pydroidrx.SchedulerPresenter;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import rx.Observable;
import rx.Scheduler;
import rx.Subscription;
import rx.subscriptions.Subscriptions;
import timber.log.Timber;

class PurgePresenterImpl extends SchedulerPresenter<PurgePresenter.View> implements PurgePresenter {

  @SuppressWarnings("WeakerAccess") @NonNull final PurgeInteractor interactor;
  @NonNull private Subscription retrievalSubscription = Subscriptions.empty();

  @Inject PurgePresenterImpl(@NonNull PurgeInteractor interactor,
      @NonNull Scheduler observeScheduler, @NonNull Scheduler subscribeScheduler) {
    super(observeScheduler, subscribeScheduler);
    this.interactor = interactor;
  }

  @Override protected void onUnbind() {
    super.onUnbind();
    unsubRetrieval();
  }

  @Override public void retrieveStaleApplications() {
    unsubRetrieval();
    retrievalSubscription = interactor.getAppEntryList()
        .zipWith(interactor.getActiveApplicationPackageNames().toList(),
            (allEntries, packageNames) -> {
              final List<String> stalePackageNames = new ArrayList<>();
              // Remove all active applications from the list of entries
              for (final String packageName : packageNames) {
                int foundLocation = -1;
                for (int i = 0; i < allEntries.size(); ++i) {
                  final PadLockEntry.AllEntries entry = allEntries.get(i);
                  if (entry.packageName().equals(packageName)) {
                    foundLocation = i;
                    break;
                  }
                }

                if (foundLocation != -1) {
                  Timber.d("Found entry for %s at %d, remove", packageName, foundLocation);
                  allEntries.remove(foundLocation);
                } else {
                  Timber.w("Package %s not found in database", packageName);
                }
              }

              // The remaining entries in the database are stale
              for (final PadLockEntry.AllEntries entry : allEntries) {
                Timber.i("Stale database entry: %s", entry);
                stalePackageNames.add(entry.packageName());
              }

              return stalePackageNames;
            })
        .flatMap(Observable::from)
        .sorted(String::compareToIgnoreCase)
        .subscribeOn(getSubscribeScheduler())
        .observeOn(getObserveScheduler())
        .subscribe(s -> getView(view -> view.onStaleApplicationRetrieved(s)), throwable -> {
          Timber.e(throwable, "onError retrieveStaleApplications");
          getView(View::onRetrievalComplete);
        }, () -> {
          unsubRetrieval();
          getView(View::onRetrievalComplete);
        });
  }

  @SuppressWarnings("WeakerAccess") void unsubRetrieval() {
    if (!retrievalSubscription.isUnsubscribed()) {
      retrievalSubscription.unsubscribe();
    }
  }
}

@@ -2114,19 +2114,35 @@
         
+f
 in
-t
+al List%3CInteger%3E
  foundLo
@@ -2151,13 +2151,29 @@
 tion
+s
  = 
--1
+new ArrayList%3C%3E()
 ;%0A  
@@ -2405,20 +2405,24 @@
 Location
- = i
+s.add(i)
 ;%0A      
@@ -2437,36 +2437,153 @@
     
-  break;%0A                  %7D
+%7D%0A                %7D%0A%0A                if (foundLocations.isEmpty()) %7B%0A                  Timber.w(%22Package %25s not found in database%22, packageName);
 %0A   
@@ -2588,33 +2588,39 @@
                %7D
-%0A
+ else %7B
 %0A               
@@ -2624,35 +2624,61 @@
     
-if (foundLocation != -1
+  for (final int foundLocation : foundLocations
 ) %7B%0A
+  
     
@@ -2783,16 +2783,18 @@
         
+  
 allEntri
@@ -2839,93 +2839,11 @@
     
-%7D else %7B%0A                  Timber.w(%22Package %25s not found in database%22, packageName);
+  %7D
 %0A   

Check for all entries in a package