/*
 * Copyright (C) 2011, The Android Open Source Project
 *
 * 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.android.server.sip;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.SystemClock;
import android.telephony.Rlog;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
import java.util.concurrent.Executor;

/**
 * Timer that can schedule events to occur even when the device is in sleep.
 */
class SipWakeupTimer extends BroadcastReceiver {
    private static final String TAG = "SipWakeupTimer";
    private static final boolean DBG = SipService.DBG && false; // STOPSHIP if true
    private static final String TRIGGER_TIME = "TriggerTime";

    private Context mContext;
    private AlarmManager mAlarmManager;

    // runnable --> time to execute in SystemClock
    private TreeSet<MyEvent> mEventQueue =
            new TreeSet<MyEvent>(new MyEventComparator());

    private PendingIntent mPendingIntent;

    private Executor mExecutor;

    public SipWakeupTimer(Context context, Executor executor) {
        mContext = context;
        mAlarmManager = (AlarmManager)
                context.getSystemService(Context.ALARM_SERVICE);

        IntentFilter filter = new IntentFilter(getAction());
        context.registerReceiver(this, filter);
        mExecutor = executor;
    }

    /**
     * Stops the timer. No event can be scheduled after this method is called.
     */
    public synchronized void stop() {
        mContext.unregisterReceiver(this);
        if (mPendingIntent != null) {
            mAlarmManager.cancel(mPendingIntent);
            mPendingIntent = null;
        }
        mEventQueue.clear();
        mEventQueue = null;
    }

    private boolean stopped() {
        if (mEventQueue == null) {
            if (DBG) log("Timer stopped");
            return true;
        } else {
            return false;
        }
    }

    private void cancelAlarm() {
        mAlarmManager.cancel(mPendingIntent);
        mPendingIntent = null;
    }

    private void recalculatePeriods() {
        if (mEventQueue.isEmpty()) return;

        MyEvent firstEvent = mEventQueue.first();
        int minPeriod = firstEvent.mMaxPeriod;
        long minTriggerTime = firstEvent.mTriggerTime;
        for (MyEvent e : mEventQueue) {
            e.mPeriod = e.mMaxPeriod / minPeriod * minPeriod;
            int interval = (int) (e.mLastTriggerTime + e.mMaxPeriod
                    - minTriggerTime);
            interval = interval / minPeriod * minPeriod;
            e.mTriggerTime = minTriggerTime + interval;
        }
        TreeSet<MyEvent> newQueue = new TreeSet<MyEvent>(
                mEventQueue.comparator());
        newQueue.addAll(mEventQueue);
        mEventQueue.clear();
        mEventQueue = newQueue;
        if (DBG) {
            log("queue re-calculated");
            printQueue();
        }
    }

    // Determines the period and the trigger time of the new event and insert it
    // to the queue.
    private void insertEvent(MyEvent event) {
        long now = SystemClock.elapsedRealtime();
        if (mEventQueue.isEmpty()) {
            event.mTriggerTime = now + event.mPeriod;
            mEventQueue.add(event);
            return;
        }
        MyEvent firstEvent = mEventQueue.first();
        int minPeriod = firstEvent.mPeriod;
        if (minPeriod <= event.mMaxPeriod) {
            event.mPeriod = event.mMaxPeriod / minPeriod * minPeriod;
            int interval = event.mMaxPeriod;
            interval -= (int) (firstEvent.mTriggerTime - now);
            interval = interval / minPeriod * minPeriod;
            event.mTriggerTime = firstEvent.mTriggerTime + interval;
            mEventQueue.add(event);
        } else {
            long triggerTime = now + event.mPeriod;
            if (firstEvent.mTriggerTime < triggerTime) {
                event.mTriggerTime = firstEvent.mTriggerTime;
                event.mLastTriggerTime -= event.mPeriod;
            } else {
                event.mTriggerTime = triggerTime;
            }
            mEventQueue.add(event);
            recalculatePeriods();
        }
    }

    /**
     * Sets a periodic timer.
     *
     * @param period the timer period; in milli-second
     * @param callback is called back when the timer goes off; the same callback
     *      can be specified in multiple timer events
     */
    public synchronized void set(int period, Runnable callback) {
        if (stopped()) return;

        long now = SystemClock.elapsedRealtime();
        MyEvent event = new MyEvent(period, callback, now);
        insertEvent(event);

        if (mEventQueue.first() == event) {
            if (mEventQueue.size() > 1) cancelAlarm();
            scheduleNext();
        }

        long triggerTime = event.mTriggerTime;
        if (DBG) {
            log("set: add event " + event + " scheduled on "
                    + showTime(triggerTime) + " at " + showTime(now)
                    + ", #events=" + mEventQueue.size());
            printQueue();
        }
    }

    /**
     * Cancels all the timer events with the specified callback.
     *
     * @param callback the callback
     */
    public synchronized void cancel(Runnable callback) {
        if (stopped() || mEventQueue.isEmpty()) return;
        if (DBG) log("cancel:" + callback);

        MyEvent firstEvent = mEventQueue.first();
        for (Iterator<MyEvent> iter = mEventQueue.iterator();
                iter.hasNext();) {
            MyEvent event = iter.next();
            if (event.mCallback == callback) {
                iter.remove();
                if (DBG) log("    cancel found:" + event);
            }
        }
        if (mEventQueue.isEmpty()) {
            cancelAlarm();
        } else if (mEventQueue.first() != firstEvent) {
            cancelAlarm();
            firstEvent = mEventQueue.first();
            firstEvent.mPeriod = firstEvent.mMaxPeriod;
            firstEvent.mTriggerTime = firstEvent.mLastTriggerTime
                    + firstEvent.mPeriod;
            recalculatePeriods();
            scheduleNext();
        }
        if (DBG) {
            log("cancel: X");
            printQueue();
        }
    }

    private void scheduleNext() {
        if (stopped() || mEventQueue.isEmpty()) return;

        if (mPendingIntent != null) {
            throw new RuntimeException("pendingIntent is not null!");
        }

        MyEvent event = mEventQueue.first();
        Intent intent = new Intent(getAction());
        intent.putExtra(TRIGGER_TIME, event.mTriggerTime);
        PendingIntent pendingIntent = mPendingIntent =
                PendingIntent.getBroadcast(mContext, 0, intent,
                        PendingIntent.FLAG_UPDATE_CURRENT);
        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                event.mTriggerTime, pendingIntent);
    }

    @Override
    public synchronized void onReceive(Context context, Intent intent) {
        // This callback is already protected by AlarmManager's wake lock.
        String action = intent.getAction();
        if (getAction().equals(action)
                && intent.getExtras().containsKey(TRIGGER_TIME)) {
            mPendingIntent = null;
            long triggerTime = intent.getLongExtra(TRIGGER_TIME, -1L);
            execute(triggerTime);
        } else {
            log("onReceive: unrecognized intent: " + intent);
        }
    }

    private void printQueue() {
        int count = 0;
        for (MyEvent event : mEventQueue) {
            log("     " + event + ": scheduled at "
                    + showTime(event.mTriggerTime) + ": last at "
                    + showTime(event.mLastTriggerTime));
            if (++count >= 5) break;
        }
        if (mEventQueue.size() > count) {
            log("     .....");
        } else if (count == 0) {
            log("     <empty>");
        }
    }

    private void execute(long triggerTime) {
        if (DBG) log("time's up, triggerTime = "
                + showTime(triggerTime) + ": " + mEventQueue.size());
        if (stopped() || mEventQueue.isEmpty()) return;

        for (MyEvent event : mEventQueue) {
            if (event.mTriggerTime != triggerTime) continue;
            if (DBG) log("execute " + event);

            event.mLastTriggerTime = triggerTime;
            event.mTriggerTime += event.mPeriod;

            // run the callback in the handler thread to prevent deadlock
            mExecutor.execute(event.mCallback);
        }
        if (DBG) {
            log("after timeout execution");
            printQueue();
        }
        scheduleNext();
    }

    private String getAction() {
        return toString();
    }

    private String showTime(long time) {
        int ms = (int) (time % 1000);
        int s = (int) (time / 1000);
        int m = s / 60;
        s %= 60;
        return String.format("%d.%d.%d", m, s, ms);
    }

    private static class MyEvent {
        int mPeriod;
        int mMaxPeriod;
        long mTriggerTime;
        long mLastTriggerTime;
        Runnable mCallback;

        MyEvent(int period, Runnable callback, long now) {
            mPeriod = mMaxPeriod = period;
            mCallback = callback;
            mLastTriggerTime = now;
        }

        @Override
        public String toString() {
            String s = super.toString();
            s = s.substring(s.indexOf("@"));
            return s + ":" + (mPeriod / 1000) + ":" + (mMaxPeriod / 1000) + ":"
                    + toString(mCallback);
        }

        private String toString(Object o) {
            String s = o.toString();
            int index = s.indexOf("$");
            if (index > 0) s = s.substring(index + 1);
            return s;
        }
    }

    // Sort the events by mMaxPeriod so that the first event can be used to
    // align events with larger periods
    private static class MyEventComparator implements Comparator<MyEvent> {
        @Override
        public int compare(MyEvent e1, MyEvent e2) {
            if (e1 == e2) return 0;
            int diff = e1.mMaxPeriod - e2.mMaxPeriod;
            if (diff == 0) diff = -1;
            return diff;
        }

        @Override
        public boolean equals(Object that) {
            return (this == that);
        }
    }

    private void log(String s) {
        Rlog.d(TAG, s);
    }
}
