package com.android.server.wifi;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.RttManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
import android.net.wifi.IRttManager;
import android.util.Slog;

import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import com.android.internal.util.StateMachine;
import com.android.internal.util.State;
import com.android.server.SystemService;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;

class RttService extends SystemService {

    public static final boolean DBG = true;

    class RttServiceImpl extends IRttManager.Stub {

        @Override
        public Messenger getMessenger() {
            return new Messenger(mClientHandler);
        }

        private class ClientHandler extends Handler {

            ClientHandler(android.os.Looper looper) {
                super(looper);
            }

            @Override
            public void handleMessage(Message msg) {

                if (DBG) Log.d(TAG, "ClientHandler got" + msg);

                switch (msg.what) {

                    case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
                        if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
                            AsyncChannel c = (AsyncChannel) msg.obj;
                            if (DBG) Slog.d(TAG, "New client listening to asynchronous messages: " +
                                    msg.replyTo);
                            ClientInfo cInfo = new ClientInfo(c, msg.replyTo);
                            mClients.put(msg.replyTo, cInfo);
                        } else {
                            Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
                        }
                        return;
                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
                        if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
                            Slog.e(TAG, "Send failed, client connection lost");
                        } else {
                            if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
                        }
                        if (DBG) Slog.d(TAG, "closing client " + msg.replyTo);
                        ClientInfo ci = mClients.remove(msg.replyTo);
                        ci.cleanup();
                        return;
                    case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
                        AsyncChannel ac = new AsyncChannel();
                        ac.connect(mContext, this, msg.replyTo);
                        return;
                }

                ClientInfo ci = mClients.get(msg.replyTo);
                if (ci == null) {
                    Slog.e(TAG, "Could not find client info for message " + msg.replyTo);
                    replyFailed(msg, RttManager.REASON_INVALID_LISTENER, "Could not find listener");
                    return;
                }

                int validCommands[] = {
                        RttManager.CMD_OP_START_RANGING,
                        RttManager.CMD_OP_STOP_RANGING
                        };

                for(int cmd : validCommands) {
                    if (cmd == msg.what) {
                        mStateMachine.sendMessage(Message.obtain(msg));
                        return;
                    }
                }

                replyFailed(msg, RttManager.REASON_INVALID_REQUEST, "Invalid request");
            }
        }

        private Context mContext;
        private RttStateMachine mStateMachine;
        private ClientHandler mClientHandler;

        RttServiceImpl() { }

        RttServiceImpl(Context context) {
            mContext = context;
        }

        public void startService(Context context) {
            mContext = context;

            HandlerThread thread = new HandlerThread("WifiRttService");
            thread.start();

            mClientHandler = new ClientHandler(thread.getLooper());
            mStateMachine = new RttStateMachine(thread.getLooper());

            mContext.registerReceiver(
                    new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            int state = intent.getIntExtra(
                                    WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_DISABLED);
                            if (DBG) Log.d(TAG, "SCAN_AVAILABLE : " + state);
                            if (state == WifiManager.WIFI_STATE_ENABLED) {
                                mStateMachine.sendMessage(CMD_DRIVER_LOADED);
                            } else if (state == WifiManager.WIFI_STATE_DISABLED) {
                                mStateMachine.sendMessage(CMD_DRIVER_UNLOADED);
                            }
                        }
                    }, new IntentFilter(WifiManager.WIFI_SCAN_AVAILABLE));

            mStateMachine.start();
        }

        private class RttRequest {
            Integer key;
            ClientInfo ci;
            RttManager.RttParams[] params;
        }

        private class ClientInfo {
            private final AsyncChannel mChannel;
            private final Messenger mMessenger;
            HashMap<Integer, RttRequest> mRequests = new HashMap<Integer,
                    RttRequest>();

            ClientInfo(AsyncChannel c, Messenger m) {
                mChannel = c;
                mMessenger = m;
            }

            boolean addRttRequest(int key, RttManager.ParcelableRttParams parcelableParams) {
                if (parcelableParams == null) {
                    return false;
                }

                RttManager.RttParams params[] = parcelableParams.mParams;

                RttRequest request = new RttRequest();
                request.key = key;
                request.ci = this;
                request.params = params;
                mRequests.put(key, request);
                mRequestQueue.add(request);
                return true;
            }

            void removeRttRequest(int key) {
                mRequests.remove(key);
            }

            void reportResult(RttRequest request, RttManager.RttResult[] results) {
                RttManager.ParcelableRttResults parcelableResults =
                        new RttManager.ParcelableRttResults(results);

                mChannel.sendMessage(RttManager.CMD_OP_SUCCEEDED,
                        0, request.key, parcelableResults);
                mRequests.remove(request.key);
            }

            void reportFailed(RttRequest request, int reason, String description) {
                reportFailed(request.key, reason, description);
            }

            void reportFailed(int key, int reason, String description) {
                Bundle bundle = new Bundle();
                bundle.putString(RttManager.DESCRIPTION_KEY, description);
                mChannel.sendMessage(RttManager.CMD_OP_FAILED, key, reason, bundle);
                mRequests.remove(key);
            }

            void reportAborted(int key) {
                mChannel.sendMessage(RttManager.CMD_OP_ABORTED, key);
                mRequests.remove(key);
            }

            void cleanup() {
                mRequests.clear();
            }
        }

        private Queue<RttRequest> mRequestQueue = new LinkedList<RttRequest>();
        private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>(4);

        private static final int BASE = Protocol.BASE_WIFI_RTT_SERVICE;

        private static final int CMD_DRIVER_LOADED                       = BASE + 0;
        private static final int CMD_DRIVER_UNLOADED                     = BASE + 1;
        private static final int CMD_ISSUE_NEXT_REQUEST                  = BASE + 2;
        private static final int CMD_RTT_RESPONSE                        = BASE + 3;

        class RttStateMachine extends StateMachine {

            DefaultState mDefaultState = new DefaultState();
            EnabledState mEnabledState = new EnabledState();
            RequestPendingState mRequestPendingState = new RequestPendingState();

            RttStateMachine(Looper looper) {
                super("RttStateMachine", looper);

                addState(mDefaultState);
                addState(mEnabledState);
                    addState(mRequestPendingState, mEnabledState);

                setInitialState(mDefaultState);
            }

            class DefaultState extends State {
                @Override
                public boolean processMessage(Message msg) {
                    if (DBG) Log.d(TAG, "DefaultState got" + msg);
                    switch (msg.what) {
                        case CMD_DRIVER_LOADED:
                            transitionTo(mEnabledState);
                            break;
                        case CMD_ISSUE_NEXT_REQUEST:
                            deferMessage(msg);
                            break;
                        case RttManager.CMD_OP_START_RANGING:
                            replyFailed(msg, RttManager.REASON_NOT_AVAILABLE, "Try later");
                            break;
                        case RttManager.CMD_OP_STOP_RANGING:
                            return HANDLED;
                        default:
                            return NOT_HANDLED;
                    }
                    return HANDLED;
                }
            }

            class EnabledState extends State {
                @Override
                public boolean processMessage(Message msg) {
                    if (DBG) Log.d(TAG, "EnabledState got" + msg);
                    ClientInfo ci = mClients.get(msg.replyTo);

                    switch (msg.what) {
                        case CMD_DRIVER_UNLOADED:
                            transitionTo(mDefaultState);
                            break;
                        case CMD_ISSUE_NEXT_REQUEST:
                            deferMessage(msg);
                            transitionTo(mRequestPendingState);
                            break;
                        case RttManager.CMD_OP_START_RANGING: {
                                RttManager.ParcelableRttParams params =
                                        (RttManager.ParcelableRttParams)msg.obj;
                                if (params == null) {
                                    replyFailed(msg,
                                            RttManager.REASON_INVALID_REQUEST, "No params");
                                } else if (ci.addRttRequest(msg.arg2, params) == false) {
                                    replyFailed(msg,
                                            RttManager.REASON_INVALID_REQUEST, "Unspecified");
                                } else {
                                    sendMessage(CMD_ISSUE_NEXT_REQUEST);
                                }
                            }
                            break;
                        case RttManager.CMD_OP_STOP_RANGING:
                            for (Iterator<RttRequest> it = mRequestQueue.iterator();
                                    it.hasNext(); ) {
                                RttRequest request = it.next();
                                if (request.key == msg.arg2) {
                                    if (DBG) Log.d(TAG, "Cancelling not-yet-scheduled RTT");
                                    mRequestQueue.remove(request);
                                    request.ci.reportAborted(request.key);
                                    break;
                                }
                            }
                            break;
                        default:
                            return NOT_HANDLED;
                    }
                    return HANDLED;
                }
            }

            class RequestPendingState extends State {
                RttRequest mOutstandingRequest;
                @Override
                public boolean processMessage(Message msg) {
                    if (DBG) Log.d(TAG, "RequestPendingState got" + msg);
                    switch (msg.what) {
                        case CMD_DRIVER_UNLOADED:
                            if (mOutstandingRequest != null) {
                                WifiNative.cancelRtt(mOutstandingRequest.params);
                                mOutstandingRequest.ci.reportAborted(mOutstandingRequest.key);
                                mOutstandingRequest = null;
                            }
                            transitionTo(mDefaultState);
                            break;
                        case CMD_ISSUE_NEXT_REQUEST:
                            if (mOutstandingRequest == null) {
                                mOutstandingRequest = issueNextRequest();
                                if (mOutstandingRequest == null) {
                                    transitionTo(mEnabledState);
                                }
                            } else {
                                /* just wait; we'll issue next request after
                                 * current one is finished */
                                if (DBG) Log.d(TAG, "Ignoring CMD_ISSUE_NEXT_REQUEST");
                            }
                            break;
                        case CMD_RTT_RESPONSE:
                            if (DBG) Log.d(TAG, "Received an RTT response");
                            mOutstandingRequest.ci.reportResult(
                                    mOutstandingRequest, (RttManager.RttResult[])msg.obj);
                            mOutstandingRequest = null;
                            sendMessage(CMD_ISSUE_NEXT_REQUEST);
                            break;
                        case RttManager.CMD_OP_STOP_RANGING:
                            if (mOutstandingRequest != null
                                    && msg.arg2 == mOutstandingRequest.key) {
                                if (DBG) Log.d(TAG, "Cancelling ongoing RTT");
                                WifiNative.cancelRtt(mOutstandingRequest.params);
                                mOutstandingRequest.ci.reportAborted(mOutstandingRequest.key);
                                mOutstandingRequest = null;
                                sendMessage(CMD_ISSUE_NEXT_REQUEST);
                            } else {
                                /* Let EnabledState handle this */
                                return NOT_HANDLED;
                            }
                            break;
                        default:
                            return NOT_HANDLED;
                    }
                    return HANDLED;
                }
            }
        }

        void replySucceeded(Message msg, Object obj) {
            if (msg.replyTo != null) {
                Message reply = Message.obtain();
                reply.what = RttManager.CMD_OP_SUCCEEDED;
                reply.arg2 = msg.arg2;
                reply.obj = obj;
                try {
                    msg.replyTo.send(reply);
                } catch (RemoteException e) {
                    // There's not much we can do if reply can't be sent!
                }
            } else {
                // locally generated message; doesn't need a reply!
            }
        }

        void replyFailed(Message msg, int reason, String description) {
            Message reply = Message.obtain();
            reply.what = RttManager.CMD_OP_FAILED;
            reply.arg1 = reason;
            reply.arg2 = msg.arg2;

            Bundle bundle = new Bundle();
            bundle.putString(RttManager.DESCRIPTION_KEY, description);
            reply.obj = bundle;

            try {
                msg.replyTo.send(reply);
            } catch (RemoteException e) {
                // There's not much we can do if reply can't be sent!
            }
        }

        private WifiNative.RttEventHandler mEventHandler = new WifiNative.RttEventHandler() {
            @Override
            public void onRttResults(RttManager.RttResult[] result) {
                mStateMachine.sendMessage(CMD_RTT_RESPONSE, result);
            }
        };

        RttRequest issueNextRequest() {
            RttRequest request = null;
            while (mRequestQueue.isEmpty() == false) {
                request = mRequestQueue.remove();
                if (WifiNative.requestRtt(request.params, mEventHandler)) {
                    if (DBG) Log.d(TAG, "Issued next RTT request");
                    return request;
                } else {
                    request.ci.reportFailed(request,
                            RttManager.REASON_UNSPECIFIED, "Failed to start");
                }
            }

            /* all requests exhausted */
            if (DBG) Log.d(TAG, "No more requests left");
            return null;
        }
    }

    private static final String TAG = "RttService";
    RttServiceImpl mImpl;

    public RttService(Context context) {
        super(context);
        Log.i(TAG, "Creating " + Context.WIFI_RTT_SERVICE);
    }

    @Override
    public void onStart() {
        mImpl = new RttServiceImpl(getContext());

        Log.i(TAG, "Starting " + Context.WIFI_RTT_SERVICE);
        publishBinderService(Context.WIFI_RTT_SERVICE, mImpl);
    }

    @Override
    public void onBootPhase(int phase) {
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            Log.i(TAG, "Registering " + Context.WIFI_RTT_SERVICE);
            if (mImpl == null) {
                mImpl = new RttServiceImpl(getContext());
            }
            mImpl.startService(getContext());
        }
    }
}
