/*
 * 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.job;

import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.birbit.android.jobqueue.Job;
import com.birbit.android.jobqueue.Params;
import com.pyamsoft.powermanager.Singleton;
import timber.log.Timber;

public abstract class ManageJob extends BaseJob implements Runnable {

  private static final long MINIMUM_PERIOD_SECONDS = 60L;
  private static final int JOB_PRIORITY = 1;

  @NonNull private final JobType jobType;
  private final boolean periodic;
  private final long periodicEnableInSeconds;
  private final long periodicDisableInSeconds;

  ManageJob(@NonNull String tag, @NonNull JobType jobType, long delayInMilliseconds,
      boolean periodic, long periodicEnableInSeconds, long periodicDisableInSeconds) {
    super(new Params(JOB_PRIORITY).addTags(tag).setDelayMs(delayInMilliseconds));
    this.jobType = jobType;
    this.periodic = periodic;
    this.periodicEnableInSeconds = periodicEnableInSeconds;
    this.periodicDisableInSeconds = periodicDisableInSeconds;
  }

  @Override public final void onRun() throws Throwable {
    run();
    Timber.d("Run job type: %s", jobType.name());
    switch (jobType) {
      case ENABLE:
        internalEnable();
        break;
      case DISABLE:
        internalDisable();
        break;
      default:
        throw new RuntimeException("Invalid job type: " + jobType.name());
    }
  }

  @CheckResult private boolean hasValidPeriodicInterval() {
    return periodicDisableInSeconds >= MINIMUM_PERIOD_SECONDS
        && periodicEnableInSeconds >= MINIMUM_PERIOD_SECONDS;
  }

  private void internalEnable() {
    if (periodic) {
      if (!hasValidPeriodicInterval()) {
        Timber.e("Not queuing period disable job with interval less than 1 minute (%s, %s)",
            periodicEnableInSeconds, periodicDisableInSeconds);
      } else {
        Timber.d("Queue periodic disable job for: %d", periodicDisableInSeconds);
        Singleton.Jobs.with(getApplicationContext())
            .addJobInBackground(
                createPeriodicDisableJob(periodicEnableInSeconds, periodicDisableInSeconds));
      }
    }
  }

  private void internalDisable() {
    if (periodic) {
      if (!hasValidPeriodicInterval()) {
        Timber.e("Not queuing period disable job with interval less than 1 minute (%s, %s)",
            periodicEnableInSeconds, periodicDisableInSeconds);
      } else {
        Timber.d("Queue periodic enable job for: %d", periodicEnableInSeconds);
        Singleton.Jobs.with(getApplicationContext())
            .addJobInBackground(
                createPeriodicEnableJob(periodicEnableInSeconds, periodicDisableInSeconds));
      }
    }
  }

  @CheckResult @NonNull
  protected abstract Job createPeriodicDisableJob(long periodicEnableInSeconds,
      long periodicDisableInSeconds);

  @CheckResult @NonNull protected abstract Job createPeriodicEnableJob(long periodicEnableInSeconds,
      long periodicDisableInSeconds);

  protected enum JobType {
    ENABLE, DISABLE
  }
}

@@ -1734,19 +1734,8 @@
 e %7B%0A
-    run();%0A
     
@@ -1776,24 +1776,36 @@
 pe.name());%0A
+    run();%0A%0A
     switch (

Fix logging ordering