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);
                        if (ci != null) 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());
        }
    }
}
