package com.fsck.k9.power;


import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;

import android.content.Context;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;

import com.fsck.k9.mail.K9MailLib;
import org.jetbrains.annotations.NotNull;
import timber.log.Timber;


public class TracingPowerManager implements com.fsck.k9.mail.power.PowerManager {
    private final static boolean TRACE = false;
    public static AtomicInteger wakeLockId = new AtomicInteger(0);
    PowerManager pm = null;
    private static TracingPowerManager tracingPowerManager;
    private Timer timer = null;

    public static synchronized TracingPowerManager getPowerManager(Context context) {
        Context appContext = context.getApplicationContext();
        if (tracingPowerManager == null) {
            if (K9MailLib.isDebug()) {
                Timber.v("Creating TracingPowerManager");
            }
            tracingPowerManager = new TracingPowerManager(appContext);
        }
        return tracingPowerManager;
    }


    private TracingPowerManager(Context context) {
        pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        if (TRACE) {
            timer = new Timer();
        }
    }

    @NotNull
    @Override
    public com.fsck.k9.mail.power.WakeLock newWakeLock(@NotNull String tag) {
        return new TracingWakeLock(PowerManager.PARTIAL_WAKE_LOCK, tag);
    }

    public TracingWakeLock newWakeLock(int flags, String tag) {
        return new TracingWakeLock(flags, tag);
    }


    public class TracingWakeLock implements com.fsck.k9.mail.power.WakeLock {
        final WakeLock wakeLock;
        final int id;
        final String tag;
        volatile TimerTask timerTask;
        volatile Long startTime = null;
        volatile Long timeout = null;

        public TracingWakeLock(int flags, String ntag) {
            tag = ntag;
            wakeLock = pm.newWakeLock(flags, tag);
            id = wakeLockId.getAndIncrement();
            if (K9MailLib.isDebug()) {
                Timber.v("TracingWakeLock for tag %s / id %d: Create", tag, id);
            }
        }

        @Override
        public void acquire(long timeout) {
            synchronized (wakeLock) {
                wakeLock.acquire(timeout);
            }
            if (K9MailLib.isDebug()) {
                Timber.v("TracingWakeLock for tag %s / id %d for %d ms: acquired", tag, id, timeout);
            }
            raiseNotification();
            if (startTime == null) {
                startTime = SystemClock.elapsedRealtime();
            }
            this.timeout = timeout;
        }

        @Override
        public void acquire() {
            synchronized (wakeLock) {
                wakeLock.acquire();
            }
            raiseNotification();
            if (K9MailLib.isDebug()) {
                Timber.w("TracingWakeLock for tag %s / id %d: acquired with no timeout.  K-9 Mail should not do this",
                        tag, id);
            }
            if (startTime == null) {
                startTime = SystemClock.elapsedRealtime();
            }
            timeout = null;
        }

        @Override
        public void setReferenceCounted(boolean counted) {
            synchronized (wakeLock) {
                wakeLock.setReferenceCounted(counted);
            }
        }

        @Override
        public void release() {
            if (startTime != null) {
                Long endTime = SystemClock.elapsedRealtime();
                if (K9MailLib.isDebug()) {
                    Timber.v("TracingWakeLock for tag %s / id %d: releasing after %d ms, timeout = %d ms",
                            tag, id, endTime - startTime, timeout);
                }
            } else {
                if (K9MailLib.isDebug()) {
                    Timber.v("TracingWakeLock for tag %s / id %d, timeout = %d ms: releasing", tag, id, timeout);
                }
            }
            cancelNotification();
            synchronized (wakeLock) {
                wakeLock.release();
            }
            startTime = null;
        }

        private void cancelNotification() {
            if (timer != null) {
                synchronized (timer) {
                    if (timerTask != null) {
                        timerTask.cancel();
                    }
                }
            }
        }

        private void raiseNotification() {
            if (timer != null) {
                synchronized (timer) {
                    if (timerTask != null) {
                        timerTask.cancel();
                        timerTask = null;
                    }
                    timerTask = new TimerTask() {
                        @Override
                        public void run() {
                            if (startTime != null) {
                                Long endTime = SystemClock.elapsedRealtime();
                                Timber.i("TracingWakeLock for tag %s / id %d: has been active for %d ms, timeout = %d ms",
                                        tag, id, endTime - startTime, timeout);

                            } else {
                                Timber.i("TracingWakeLock for tag %s / id %d: still active, timeout = %d ms",
                                        tag, id, timeout);
                            }
                        }

                    };
                    timer.schedule(timerTask, 1000, 1000);
                }
            }
        }
    }
}

@@ -26,60 +26,8 @@
 ;%0A%0A%0A
-import java.util.Timer;%0Aimport java.util.TimerTask;%0A
 impo
@@ -72,16 +72,16 @@
 nteger;%0A
+
 %0Aimport 
@@ -401,56 +401,8 @@
 r %7B%0A
-    private final static boolean TRACE = false;%0A
     
@@ -555,40 +555,8 @@
 ger;
-%0A    private Timer timer = null;
 %0A%0A  
@@ -1112,72 +1112,8 @@
 E);%0A
-        if (TRACE) %7B%0A            timer = new Timer();%0A        %7D%0A
     
@@ -1583,46 +1583,8 @@
 ag;%0A
-        volatile TimerTask timerTask;%0A
     
@@ -2298,41 +2298,9 @@
   %7D%0A
-            raiseNotification();
 %0A
+
     
@@ -2594,41 +2594,9 @@
   %7D%0A
-            raiseNotification();
 %0A
+
     
@@ -3740,42 +3740,9 @@
   %7D%0A
-            cancelNotification();
 %0A
+
     
@@ -3817,32 +3817,32 @@
 ;%0A            %7D%0A
+
             star
@@ -3868,1397 +3868,8 @@
    %7D
-%0A%0A        private void cancelNotification() %7B%0A            if (timer != null) %7B%0A                synchronized (timer) %7B%0A                    if (timerTask != null) %7B%0A                        timerTask.cancel();%0A                    %7D%0A                %7D%0A            %7D%0A        %7D%0A%0A        private void raiseNotification() %7B%0A            if (timer != null) %7B%0A                synchronized (timer) %7B%0A                    if (timerTask != null) %7B%0A                        timerTask.cancel();%0A                        timerTask = null;%0A                    %7D%0A                    timerTask = new TimerTask() %7B%0A                        @Override%0A                        public void run() %7B%0A                            if (startTime != null) %7B%0A                                Long endTime = SystemClock.elapsedRealtime();%0A                                Timber.i(%22TracingWakeLock for tag %25s / id %25d: has been active for %25d ms, timeout = %25d ms%22,%0A                                        tag, id, endTime - startTime, timeout);%0A%0A                            %7D else %7B%0A                                Timber.i(%22TracingWakeLock for tag %25s / id %25d: still active, timeout = %25d ms%22,%0A                                        tag, id, timeout);%0A                            %7D%0A                        %7D%0A%0A                    %7D;%0A                    timer.schedule(timerTask, 1000, 1000);%0A                %7D%0A            %7D%0A        %7D
 %0A   

Remove (unused) timer functionality from TracingPowerManager