/*
 * Copyright (C) 2013 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.internal.telephony;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Message;
import android.os.PowerManager;
import android.telephony.Rlog;

import com.android.internal.util.State;
import com.android.internal.util.StateMachine;

/**
 * Generic state machine for handling messages and waiting for ordered broadcasts to complete.
 * Subclasses implement {@link #handleSmsMessage}, which returns true to transition into waiting
 * state, or false to remain in idle state. The wakelock is acquired on exit from idle state,
 * and is released a few seconds after returning to idle state, or immediately upon calling
 * {@link #quit}.
 */
public abstract class WakeLockStateMachine extends StateMachine {
    protected static final boolean DBG = true;    // TODO: change to false

    private final PowerManager.WakeLock mWakeLock;

    /** New message to process. */
    public static final int EVENT_NEW_SMS_MESSAGE = 1;

    /** Result receiver called for current cell broadcast. */
    protected static final int EVENT_BROADCAST_COMPLETE = 2;

    /** Release wakelock after a short timeout when returning to idle state. */
    static final int EVENT_RELEASE_WAKE_LOCK = 3;

    static final int EVENT_UPDATE_PHONE_OBJECT = 4;

    protected PhoneBase mPhone;

    protected Context mContext;

    /** Wakelock release delay when returning to idle state. */
    private static final int WAKE_LOCK_TIMEOUT = 3000;

    private final DefaultState mDefaultState = new DefaultState();
    private final IdleState mIdleState = new IdleState();
    private final WaitingState mWaitingState = new WaitingState();

    protected WakeLockStateMachine(String debugTag, Context context, PhoneBase phone) {
        super(debugTag);

        mContext = context;
        mPhone = phone;

        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, debugTag);
        mWakeLock.acquire();    // wake lock released after we enter idle state

        addState(mDefaultState);
        addState(mIdleState, mDefaultState);
        addState(mWaitingState, mDefaultState);
        setInitialState(mIdleState);
    }

    public void updatePhoneObject(PhoneBase phone) {
        sendMessage(EVENT_UPDATE_PHONE_OBJECT, phone);
    }

    /**
     * Tell the state machine to quit after processing all messages.
     */
    public final void dispose() {
        quit();
    }

    @Override
    protected void onQuitting() {
        // fully release the wakelock
        while (mWakeLock.isHeld()) {
            mWakeLock.release();
        }
    }

    /**
     * Send a message with the specified object for {@link #handleSmsMessage}.
     * @param obj the object to pass in the msg.obj field
     */
    public final void dispatchSmsMessage(Object obj) {
        sendMessage(EVENT_NEW_SMS_MESSAGE, obj);
    }

    /**
     * This parent state throws an exception (for debug builds) or prints an error for unhandled
     * message types.
     */
    class DefaultState extends State {
        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case EVENT_UPDATE_PHONE_OBJECT: {
                    mPhone = (PhoneBase) msg.obj;
                    log("updatePhoneObject: phone=" + mPhone.getClass().getSimpleName());
                    break;
                }
                default: {
                    String errorText = "processMessage: unhandled message type " + msg.what;
                    if (Build.IS_DEBUGGABLE) {
                        throw new RuntimeException(errorText);
                    } else {
                        loge(errorText);
                    }
                    break;
                }
            }
            return HANDLED;
        }
    }

    /**
     * Idle state delivers Cell Broadcasts to receivers. It acquires the wakelock, which is
     * released when the broadcast completes.
     */
    class IdleState extends State {
        @Override
        public void enter() {
            sendMessageDelayed(EVENT_RELEASE_WAKE_LOCK, WAKE_LOCK_TIMEOUT);
        }

        @Override
        public void exit() {
            mWakeLock.acquire();
            if (DBG) log("acquired wakelock, leaving Idle state");
        }

        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case EVENT_NEW_SMS_MESSAGE:
                    // transition to waiting state if we sent a broadcast
                    if (handleSmsMessage(msg)) {
                        transitionTo(mWaitingState);
                    }
                    return HANDLED;

                case EVENT_RELEASE_WAKE_LOCK:
                    mWakeLock.release();
                    if (DBG) {
                        if (mWakeLock.isHeld()) {
                            // this is okay as long as we call release() for every acquire()
                            log("mWakeLock is still held after release");
                        } else {
                            log("mWakeLock released");
                        }
                    }
                    return HANDLED;

                default:
                    return NOT_HANDLED;
            }
        }
    }

    /**
     * Waiting state waits for the result receiver to be called for the current cell broadcast.
     * In this state, any new cell broadcasts are deferred until we return to Idle state.
     */
    class WaitingState extends State {
        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case EVENT_NEW_SMS_MESSAGE:
                    log("deferring message until return to idle");
                    deferMessage(msg);
                    return HANDLED;

                case EVENT_BROADCAST_COMPLETE:
                    log("broadcast complete, returning to idle");
                    transitionTo(mIdleState);
                    return HANDLED;

                case EVENT_RELEASE_WAKE_LOCK:
                    mWakeLock.release();    // decrement wakelock from previous entry to Idle
                    if (!mWakeLock.isHeld()) {
                        // wakelock should still be held until 3 seconds after we enter Idle
                        loge("mWakeLock released while still in WaitingState!");
                    }
                    return HANDLED;

                default:
                    return NOT_HANDLED;
            }
        }
    }

    /**
     * Implemented by subclass to handle messages in {@link IdleState}.
     * @param message the message to process
     * @return true to transition to {@link WaitingState}; false to stay in {@link IdleState}
     */
    protected abstract boolean handleSmsMessage(Message message);

    /**
     * BroadcastReceiver to send message to return to idle state.
     */
    protected final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            sendMessage(EVENT_BROADCAST_COMPLETE);
        }
    };

    /**
     * Log with debug level.
     * @param s the string to log
     */
    @Override
    protected void log(String s) {
        Rlog.d(getName(), s);
    }

    /**
     * Log with error level.
     * @param s the string to log
     */
    @Override
    protected void loge(String s) {
        Rlog.e(getName(), s);
    }

    /**
     * Log with error level.
     * @param s the string to log
     * @param e is a Throwable which logs additional information.
     */
    @Override
    protected void loge(String s, Throwable e) {
        Rlog.e(getName(), s, e);
    }
}
