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

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeSet;
import java.util.concurrent.Executor;
import javax.sip.SipException;

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

    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 synchronized boolean stopped() {
        if (mEventQueue == null) {
            Log.w(TAG, "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((Collection<MyEvent>) mEventQueue);
        mEventQueue.clear();
        mEventQueue = newQueue;
        if (DEBUG_TIMER) {
            Log.d(TAG, "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 (DEBUG_TIMER) {
            Log.d(TAG, " add event " + event + " scheduled at "
                    + 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 (DEBUG_TIMER) Log.d(TAG, "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 (DEBUG_TIMER) Log.d(TAG, "    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 (DEBUG_TIMER) {
            Log.d(TAG, "after cancel:");
            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 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.d(TAG, "unrecognized intent: " + intent);
        }
    }

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

    private synchronized void execute(long triggerTime) {
        if (DEBUG_TIMER) Log.d(TAG, "time's up, triggerTime = "
                + showTime(triggerTime) + ": " + mEventQueue.size());
        if (stopped() || mEventQueue.isEmpty()) return;

        for (MyEvent event : mEventQueue) {
            if (event.mTriggerTime != triggerTime) break;
            if (DEBUG_TIMER) Log.d(TAG, "execute " + event);

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

            // run the callback in the handler thread to prevent deadlock
            mExecutor.execute(event.mCallback);
        }
        if (DEBUG_TIMER) {
            Log.d(TAG, "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;
        }
    }

    private static class MyEventComparator implements Comparator<MyEvent> {
        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;
        }

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