/*
 * Copyright (C) 2006 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.AsyncQueryHandler;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Contacts;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

/**
 * ASYNCHRONOUS QUERY API
 */

public class CallerInfoAsyncQuery {
    
    private static final boolean DBG = false;
    private static final String LOG_TAG = "PHONE";
    
    private static final int EVENT_NEW_QUERY = 1;
    private static final int EVENT_ADD_LISTENER = 2;
    private static final int EVENT_END_OF_QUEUE = 3;
    private static final int EVENT_EMERGENCY_NUMBER = 4;
    private static final int EVENT_VOICEMAIL_NUMBER = 5;

    private CallerInfoAsyncQueryHandler mHandler;

    // Don't keep checking VM if it's going to throw an exception for this proc.
    private static boolean sSkipVmCheck = false;

    /**
     * Interface for a CallerInfoAsyncQueryHandler result return.
     */
    public interface OnQueryCompleteListener {
        /**
         * Called when the query is complete.  
         */  
        public void onQueryComplete(int token, Object cookie, CallerInfo ci);
    }
    
    
    /**
     * Wrap the cookie from the WorkerArgs with additional information needed by our
     * classes. 
     */
    private static final class CookieWrapper {
        public OnQueryCompleteListener listener;
        public Object cookie;
        public int event;
        public String number;
    }    
    
    
    /**
     * Simple exception used to communicate problems with the query pool.
     */
    public static class QueryPoolException extends SQLException {
        public QueryPoolException(String error) {
            super(error);
        }
    }
    
    /**
     * Our own implementation of the AsyncQueryHandler.
     */
    private class CallerInfoAsyncQueryHandler extends AsyncQueryHandler {
        
        /**
         * The information relevant to each CallerInfo query.  Each query may have multiple
         * listeners, so each AsyncCursorInfo is associated with 2 or more CookieWrapper
         * objects in the queue (one with a new query event, and one with a end event, with
         * 0 or more additional listeners in between).
         */
        private Context mQueryContext;
        private Uri mQueryUri;
        private CallerInfo mCallerInfo;
        
        /**
         * Our own query worker thread.
         * 
         * This thread handles the messages enqueued in the looper.  The normal sequence
         * of events is that a new query shows up in the looper queue, followed by 0 or
         * more add listener requests, and then an end request.  Of course, these requests
         * can be interlaced with requests from other tokens, but is irrelevant to this
         * handler since the handler has no state.
         * 
         * Note that we depend on the queue to keep things in order; in other words, the
         * looper queue must be FIFO with respect to input from the synchronous startQuery 
         * calls and output to this handleMessage call.
         * 
         * This use of the queue is required because CallerInfo objects may be accessed
         * multiple times before the query is complete.  All accesses (listeners) must be
         * queued up and informed in order when the query is complete.
         */
        protected class CallerInfoWorkerHandler extends WorkerHandler {
            public CallerInfoWorkerHandler(Looper looper) {
                super(looper);
            }

            @Override
            public void handleMessage(Message msg) {
                WorkerArgs args = (WorkerArgs) msg.obj;
                CookieWrapper cw = (CookieWrapper) args.cookie;
                
                if (cw == null) {
                    // Normally, this should never be the case for calls originating
                    // from within this code.
                    // However, if there is any code that this Handler calls (such as in 
                    // super.handleMessage) that DOES place unexpected messages on the
                    // queue, then we need pass these messages on.
                    if (DBG) log("Unexpected command (CookieWrapper is null): " + msg.what + 
                            " ignored by CallerInfoWorkerHandler, passing onto parent.");
                    
                    super.handleMessage(msg);
                } else {
                    
                    if (DBG) log("Processing event: " + cw.event + " token (arg1): " + msg.arg1 + 
                            " command: " + msg.what + " query URI: " + args.uri);
                    
                    switch (cw.event) {
                        case EVENT_NEW_QUERY:
                            //start the sql command.
                            super.handleMessage(msg);
                            break;

                        // shortcuts to avoid query for recognized numbers.
                        case EVENT_EMERGENCY_NUMBER:
                        case EVENT_VOICEMAIL_NUMBER:
                            
                        case EVENT_ADD_LISTENER:
                        case EVENT_END_OF_QUEUE:
                            // query was already completed, so just send the reply.
                            // passing the original token value back to the caller
                            // on top of the event values in arg1.
                            Message reply = args.handler.obtainMessage(msg.what);
                            reply.obj = args;
                            reply.arg1 = msg.arg1;
        
                            reply.sendToTarget();
        
                            break;
                        default:
                    }
                }
            }
        }
        
        
        /**
         * Asynchronous query handler class for the contact / callerinfo object.
         */
        private CallerInfoAsyncQueryHandler(Context context) {
            super(context.getContentResolver());
        }

        @Override
        protected Handler createHandler(Looper looper) {
            return new CallerInfoWorkerHandler(looper);
        }

        /**
         * Overrides onQueryComplete from AsyncQueryHandler.
         * 
         * This method takes into account the state of this class; we construct the CallerInfo
         * object only once for each set of listeners. When the query thread has done its work
         * and calls this method, we inform the remaining listeners in the queue, until we're 
         * out of listeners.  Once we get the message indicating that we should expect no new 
         * listeners for this CallerInfo object, we release the AsyncCursorInfo back into the 
         * pool.
         */
        @Override
        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
            if (DBG) log("query complete for token: " + token);
            
            //get the cookie and notify the listener.
            CookieWrapper cw = (CookieWrapper) cookie;
            if (cw == null) {
                // Normally, this should never be the case for calls originating
                // from within this code.
                // However, if there is any code that calls this method, we should 
                // check the parameters to make sure they're viable.
                if (DBG) log("Cookie is null, ignoring onQueryComplete() request.");
                return;
            }
            
            if (cw.event == EVENT_END_OF_QUEUE) {
                release();
                return;
            }

            // check the token and if needed, create the callerinfo object.
            if (mCallerInfo == null) {
                if ((mQueryContext == null) || (mQueryUri == null)) {
                    throw new QueryPoolException
                            ("Bad context or query uri, or CallerInfoAsyncQuery already released.");
                }
                
                // adjust the callerInfo data as needed, and only if it was set from the
                // initial query request.
                // Change the callerInfo number ONLY if it is an emergency number or the
                // voicemail number, and adjust other data (including photoResource) 
                // accordingly.
                if (cw.event == EVENT_EMERGENCY_NUMBER) {
                    mCallerInfo = new CallerInfo();
                    // Note we're setting the phone number here (refer to javadoc
                    // comments at the top of CallerInfo class). 
                    mCallerInfo.phoneNumber = mQueryContext.getString(com.android.internal
                            .R.string.emergency_call_dialog_number_for_display);
                    mCallerInfo.photoResource = com.android.internal.R.drawable.picture_emergency;

                } else if (cw.event == EVENT_VOICEMAIL_NUMBER) {
                    mCallerInfo = new CallerInfo();
                    try {
                        // Note we're setting the phone number here (refer to javadoc
                        // comments at the top of CallerInfo class). 
                        mCallerInfo.phoneNumber = 
                                TelephonyManager.getDefault().getVoiceMailAlphaTag();
                    } catch (SecurityException ex) {
                        // Should never happen: if this process does not have
                        // permission to retrieve VM tag, it should not have
                        // permission to retrieve VM number and would not generate
                        // an EVENT_VOICEMAIL_NUMBER.  But if it happens, don't crash.
                    }
                } else { 
                    mCallerInfo = CallerInfo.getCallerInfo(mQueryContext, mQueryUri, cursor);
                    // Use the number entered by the user for display.
                    if (!TextUtils.isEmpty(cw.number)) {
                        mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number);
                    }
                }
                
                if (DBG) log("constructing CallerInfo object for token: " + token);
                
                //notify that we can clean up the queue after this.
                CookieWrapper endMarker = new CookieWrapper();
                endMarker.event = EVENT_END_OF_QUEUE;
                startQuery (token, endMarker, null, null, null, null, null);
            }
            
            //notify the listener that the query is complete.
            if (cw.listener != null) {
                if (DBG) log("notifying listener: " + cw.listener.getClass().toString() + 
                        " for token: " + token);
                cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo);
            }
        }
    }
    
    /**
     * Private constructor for factory methods.
     */
    private CallerInfoAsyncQuery() {
    }

    
    /**
     * Factory method to start query with a Uri query spec
     */
    public static CallerInfoAsyncQuery startQuery(int token, Context context, Uri contactRef, 
            OnQueryCompleteListener listener, Object cookie) {
        
        CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
        c.allocate(context, contactRef);

        if (DBG) log("starting query for URI: " + contactRef + " handler: " + c.toString());
        
        //create cookieWrapper, start query
        CookieWrapper cw = new CookieWrapper();
        cw.listener = listener;
        cw.cookie = cookie;
        cw.event = EVENT_NEW_QUERY;
        
        c.mHandler.startQuery (token, cw, contactRef, null, null, null, null);
        
        return c;
    }
    
    /**
     * Factory method to start query with a number
     */
    public static CallerInfoAsyncQuery startQuery(int token, Context context, String number, 
            OnQueryCompleteListener listener, Object cookie) {
        //contruct the URI object and start Query.
        Uri contactRef = Uri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL, number);
        
        CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
        c.allocate(context, contactRef);

        if (DBG) log("starting query for number: " + number + " handler: " + c.toString());
        
        //create cookieWrapper, start query
        CookieWrapper cw = new CookieWrapper();
        cw.listener = listener;
        cw.cookie = cookie;
        cw.number = number;

        // check to see if these are recognized numbers, and use shortcuts if we can. 
        if (PhoneNumberUtils.isEmergencyNumber(number)) {
            cw.event = EVENT_EMERGENCY_NUMBER;
        } else {
            String vmNumber = null;
            if (!sSkipVmCheck){
                try {
                    vmNumber = TelephonyManager.getDefault().getVoiceMailNumber();
                } catch (SecurityException ex) {
                    // Don't crash if this process doesn't have permission to 
                    // retrieve VM number.  It's still allowed to look up caller info.
                    // But don't try it again.
                    sSkipVmCheck = true;
                }
            }
            if (PhoneNumberUtils.compare(number, vmNumber)) { 
                cw.event = EVENT_VOICEMAIL_NUMBER;
            } else {
                cw.event = EVENT_NEW_QUERY;
            }
        }

        c.mHandler.startQuery (token, cw, contactRef, null, null, null, null);
        
        return c;
   }
    
    /**
     * Method to add listeners to a currently running query
     */
    public void addQueryListener(int token, OnQueryCompleteListener listener, Object cookie) {

        if (DBG) log("adding listener to query: " + mHandler.mQueryUri + " handler: " + 
                mHandler.toString());
        
        //create cookieWrapper, add query request to end of queue.
        CookieWrapper cw = new CookieWrapper();
        cw.listener = listener;
        cw.cookie = cookie;
        cw.event = EVENT_ADD_LISTENER;
        
        mHandler.startQuery (token, cw, null, null, null, null, null);
    }

    /**
     * Method to create a new CallerInfoAsyncQueryHandler object, ensuring correct
     * state of context and uri.
     */
    private void allocate (Context context, Uri contactRef) {
        if ((context == null) || (contactRef == null)){
            throw new QueryPoolException("Bad context or query uri.");
        }
        mHandler = new CallerInfoAsyncQueryHandler(context);
        mHandler.mQueryContext = context;
        mHandler.mQueryUri = contactRef;
    }

    /**
     * Releases the relevant data.
     */
    private void release () {
        mHandler.mQueryContext = null;
        mHandler.mQueryUri = null;
        mHandler.mCallerInfo = null;
        mHandler = null;
    }
    
    /**
     * static logging method
     */
    private static void log(String msg) {
        Log.d(LOG_TAG, msg);
    }   
}

