/*
 * 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.powermanager.dagger.logger;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.pyamsoft.powermanager.app.logger.LoggerPresenter;
import com.pyamsoft.pydroidrx.SchedulerPresenter;
import com.pyamsoft.pydroidrx.SubscriptionHelper;
import java.util.Locale;
import javax.inject.Inject;
import rx.Observable;
import rx.Scheduler;
import rx.Subscription;
import rx.functions.Func1;
import rx.subscriptions.CompositeSubscription;
import rx.subscriptions.Subscriptions;
import timber.log.Timber;

class LoggerPresenterImpl extends SchedulerPresenter<LoggerPresenter.Provider>
    implements LoggerPresenter {

  @SuppressWarnings("WeakerAccess") @NonNull final LoggerInteractor interactor;
  @SuppressWarnings("WeakerAccess") @NonNull Subscription logContenSubscription =
      Subscriptions.empty();
  @NonNull private CompositeSubscription logSubscriptions = new CompositeSubscription();

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

  @Override protected void onBind() {
    super.onBind();
    retrieveLogContents();
  }

  private void retrieveLogContents() {
    SubscriptionHelper.unsubscribe(logContenSubscription);
    getView(Provider::onPrepareLogContentRetrieval);
    logContenSubscription = interactor.getLogContents()
        .subscribeOn(getSubscribeScheduler())
        .observeOn(getObserveScheduler())
        .subscribe(logLine -> getView(view -> view.onLogContentRetrieved(logLine)),
            throwable -> Timber.e(throwable, "onError: Failed to retrieve log contents: %s",
                interactor.getLogType()), () -> {
              getView(Provider::onAllLogContentsRetrieved);
              SubscriptionHelper.unsubscribe(logContenSubscription);
            });
  }

  @Override protected void onUnbind() {
    super.onUnbind();
    logSubscriptions.clear();
    SubscriptionHelper.unsubscribe(logContenSubscription);
  }

  @Override public void log(@NonNull String fmt, @Nullable Object... args) {
    final Subscription logSubscription = interactor.isLoggingEnabled().filter(enabled -> {
      Timber.d("Filter out logging not enabled ");
      return !enabled;
    }).flatMap(new Func1<Boolean, Observable<Boolean>>() {
      @Override public Observable<Boolean> call(Boolean loggingEnabled) {
        final Observable<Boolean> writeAppendResult;
        if (loggingEnabled) {
          Timber.d("Format message");
          final String message = String.format(Locale.getDefault(), fmt, args);
          Timber.d("Attempt to append to log");
          writeAppendResult = interactor.appendToLog(message);
        } else {
          Timber.w("Logging disabled, return false");
          writeAppendResult = Observable.just(false);
        }
        return writeAppendResult;
      }
    }).subscribeOn(getSubscribeScheduler()).observeOn(getObserveScheduler()).subscribe(success -> {
      Timber.d("Successfully logged message to log file: %s", success);
      // TODO anything else?
    }, throwable -> {
      Timber.e(throwable, "onError: Unable to successfully log message to log file");
      // TODO Any other error handling?
    });

    logSubscriptions.add(logSubscription);
  }

  @Override public void deleteLog() {

  }
}

@@ -917,24 +917,62 @@
 til.Locale;%0A
+import java.util.concurrent.TimeUnit;%0A
 import javax
@@ -1387,16 +1387,143 @@
 ractor;%0A
+  @SuppressWarnings(%22WeakerAccess%22) @NonNull final CompositeSubscription logSubscriptions =%0A      new CompositeSubscription();%0A
   @Suppr
@@ -1632,33 +1632,50 @@
 %0A  @
-NonNull private Composite
+SuppressWarnings(%22WeakerAccess%22) @NonNull 
 Subs
@@ -1675,33 +1675,38 @@
 ll Subscription 
-l
+clearL
 ogSubscriptions 
@@ -1707,25 +1707,17 @@
 tion
-s
  =
- new Composite
+%0A      
 Subs
@@ -1720,24 +1720,31 @@
 Subscription
+s.empty
 ();%0A%0A  @Inje
@@ -2878,32 +2878,54 @@
 ntenSubscription
+, clearLogSubscription
 );%0A  %7D%0A%0A  @Overr
@@ -4138,16 +4138,49 @@
    %7D);%0A%0A
+    queueClearLogSubscription();%0A
     logS
@@ -4225,44 +4225,784 @@
 %0A%0A  
-@Override public void deleteLog() %7B%0A
+private void queueClearLogSubscription() %7B%0A    Timber.d(%22Queue to clear the Log CompositeSubscription in 1 minute%22);%0A    SubscriptionHelper.unsubscribe(clearLogSubscription);%0A    clearLogSubscription = Observable.just(true)%0A        .delay(1, TimeUnit.MINUTES)%0A        .subscribeOn(getSubscribeScheduler())%0A        .observeOn(getObserveScheduler())%0A        .subscribe(aBoolean -%3E %7B%0A              Timber.d(%22Clear composite Log subscriptions%22);%0A              logSubscriptions.clear();%0A            %7D, throwable -%3E Timber.e(throwable, %22onError clearing composite subscription%22),%0A            () -%3E SubscriptionHelper.unsubscribe(clearLogSubscription));%0A  %7D%0A%0A  @Override public void deleteLog() %7B%0A    Timber.d(%22Delete log file for %25s%22, interactor.getLogType());%0A    Timber.w(%22TODO%22);
 %0A  %7D

Clear the composite sub after 1 minute of no activity