/*
 * Copyright (C) 2016 Google Inc.
 *
 * 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.googlecode.android_scripting.facade;

import java.util.HashMap;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;

import org.json.JSONException;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.event.Event;
import com.googlecode.android_scripting.event.EventObserver;
import com.googlecode.android_scripting.event.EventServer;
import com.googlecode.android_scripting.future.FutureResult;
import com.googlecode.android_scripting.jsonrpc.JsonBuilder;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcDefault;
import com.googlecode.android_scripting.rpc.RpcDeprecated;
import com.googlecode.android_scripting.rpc.RpcName;
import com.googlecode.android_scripting.rpc.RpcOptional;
import com.googlecode.android_scripting.rpc.RpcParameter;

/**
 * Manage the event queue. <br>
 * <br>
 * <b>Usage Notes:</b><br>
 * EventFacade APIs interact with the Event Queue (a data buffer containing up to 1024 event
 * entries).<br>
 * Events are automatically entered into the Event Queue following API calls such as startSensing()
 * and startLocating().<br>
 * The Event Facade provides control over how events are entered into (and removed from) the Event
 * Queue.<br>
 * The Event Queue provides a useful means of recording background events (such as sensor data) when
 * the phone is busy with foreground activities.
 *
 * @author Felix Arends (felix.arends@gmail.com)
 */
public class EventFacade extends RpcReceiver {
    /**
     * The maximum length of the event queue. Old events will be discarded when this limit is
     * exceeded.
     */
    private static final int MAX_QUEUE_SIZE = 1024;
    private final Queue<Event> mEventQueue = new ConcurrentLinkedQueue<Event>();
    private final CopyOnWriteArrayList<EventObserver> mGlobalEventObservers =
            new CopyOnWriteArrayList<EventObserver>();
    private final Multimap<String, EventObserver> mNamedEventObservers = Multimaps
            .synchronizedListMultimap(ArrayListMultimap.<String, EventObserver> create());
    private EventServer mEventServer = null;
    private final HashMap<String, BroadcastListener> mBroadcastListeners =
            new HashMap<String, BroadcastListener>();
    private final Context mContext;
    private boolean bEventServerRunning;

    public EventFacade(FacadeManager manager) {
        super(manager);
        mContext = manager.getService().getApplicationContext();
        Log.v("Creating new EventFacade Instance()");
        bEventServerRunning = false;
    }

    /**
     * Example (python): droid.eventClearBuffer()
     */
    @Rpc(description = "Clears all events from the event buffer.")
    public void eventClearBuffer() {
        mEventQueue.clear();
    }

    /**
     * Registers a listener for a new broadcast signal
     */
    @Rpc(description = "Registers a listener for a new broadcast signal")
    public boolean eventRegisterForBroadcast(
            @RpcParameter(name = "category") String category,
            @RpcParameter(name = "enqueue",
                    description = "Should this events be added to the event queue or only dispatched") @RpcDefault(value = "true") Boolean enqueue) {
        if (mBroadcastListeners.containsKey(category)) {
            return false;
        }

        BroadcastListener b = new BroadcastListener(this, enqueue.booleanValue());
        IntentFilter c = new IntentFilter(category);
        mContext.registerReceiver(b, c);
        mBroadcastListeners.put(category, b);

        return true;
    }

    @Rpc(description = "Stop listening for a broadcast signal")
    public void eventUnregisterForBroadcast(
            @RpcParameter(name = "category") String category) {
        if (!mBroadcastListeners.containsKey(category)) {
            return;
        }

        mContext.unregisterReceiver(mBroadcastListeners.get(category));
        mBroadcastListeners.remove(category);
    }

    @Rpc(description = "Lists all the broadcast signals we are listening for")
    public Set<String> eventGetBrodcastCategories() {
        return mBroadcastListeners.keySet();
    }

    /**
     * Actual data returned in the map will depend on the type of event.
     *
     * <pre>
     * Example (python):
     *     import android, time
     *     droid = android.Android()
     *     droid.startSensing()
     *     time.sleep(1)
     *     droid.eventClearBuffer()
     *     time.sleep(1)
     *     e = eventPoll(1).result
     *     event_entry_number = 0
     *     x = e[event_entry_ number]['data']['xforce']
     * </pre>
     *
     * e has the format:<br>
     * [{u'data': {u'accuracy': 0, u'pitch': -0.48766891956329345, u'xmag': -5.6875, u'azimuth':
     * 0.3312483489513397, u'zforce': 8.3492730000000002, u'yforce': 4.5628165999999997, u'time':
     * 1297072704.813, u'ymag': -11.125, u'zmag': -42.375, u'roll': -0.059393649548292161,
     * u'xforce': 0.42223078000000003}, u'name': u'sensors', u'time': 1297072704813000L}]<br>
     * x has the string value of the x force data (0.42223078000000003) at the time of the event
     * entry. </pre>
     */

    @Rpc(description = "Returns and removes the oldest n events (i.e. location or sensor update, etc.) from the event buffer.",
            returns = "A List of Maps of event properties.")
    public List<Event> eventPoll(
            @RpcParameter(name = "number_of_events") @RpcDefault("1") Integer number_of_events) {
        List<Event> events = Lists.newArrayList();
        for (int i = 0; i < number_of_events; i++) {
            Event event = mEventQueue.poll();
            if (event == null) {
                break;
            }
            events.add(event);
        }
        return events;
    }

    @Rpc(description = "Blocks until an event with the supplied name occurs. Event is removed from the buffer if removeEvent is True.",
            returns = "Map of event properties.")
    public Event eventWaitFor(
            @RpcParameter(name = "eventName")
            final String eventName,
            @RpcParameter(name = "removeEvent")
            final Boolean removeEvent,
            @RpcParameter(name = "timeout", description = "the maximum time to wait (in ms)") @RpcOptional Integer timeout)
            throws InterruptedException {
        Event result = null;
        final FutureResult<Event> futureEvent;
        synchronized (mEventQueue) { // First check to make sure it isn't already there
            for (Event event : mEventQueue) {
                if (event.getName().equals(eventName)) {
                    result = event;
                    if (removeEvent)
                        mEventQueue.remove(event);
                    return result;
                }
            }
            futureEvent = new FutureResult<Event>();
            addNamedEventObserver(eventName, new EventObserver() {
                @Override
                public void onEventReceived(Event event) {
                    if (event.getName().equals(eventName)) {
                        synchronized (futureEvent) {
                            if (!futureEvent.isDone()) {
                                futureEvent.set(event);
                                // TODO(navtej) Remove log.
                                Log.v(String.format("Removeing observer (%s) got event  (%s)",
                                        this,
                                        event));
                                removeEventObserver(this);
                            }
                            if (removeEvent)
                                mEventQueue.remove(event);
                        }
                    }
                }
            });
        }
        if (futureEvent != null) {
            if (timeout != null) {
                result = futureEvent.get(timeout, TimeUnit.MILLISECONDS);
            } else {
                result = futureEvent.get();
            }
        }
        return result;
    }

    @Rpc(description = "Blocks until an event occurs. The returned event is removed from the buffer.",
            returns = "Map of event properties.")
    public Event eventWait(
            @RpcParameter(name = "timeout", description = "the maximum time to wait") @RpcOptional Integer timeout)
            throws InterruptedException {
        Event result = null;
        final FutureResult<Event> futureEvent = new FutureResult<Event>();
        EventObserver observer;
        synchronized (mEventQueue) { // Anything in queue?
            if (mEventQueue.size() > 0) {
                return mEventQueue.poll(); // return it.
            }
            observer = new EventObserver() {
                @Override
                public void onEventReceived(Event event) { // set up observer for any events.
                    synchronized (futureEvent) {
                        if (!futureEvent.isDone()) {
                            futureEvent.set(event);
                            // TODO(navtej) Remove log.
                            Log.v(String.format("onEventReceived for event (%s)", event));
                        }
                    }
                }
            };
            addGlobalEventObserver(observer);
        }
        if (timeout != null) {
            result = futureEvent.get(timeout, TimeUnit.MILLISECONDS);
        } else {
            result = futureEvent.get();
        }
        if (result != null) {
            mEventQueue.remove(result);
        }
        // TODO(navtej) Remove log.
        Log.v(String.format("Removeing observer (%s) got event  (%s)", observer, result));
        if (observer != null) {
            removeEventObserver(observer); // Make quite sure this goes away.
        }
        return result;
    }

    /**
     * <pre>
     * Example:
     *   import android
     *   from datetime import datetime
     *   droid = android.Android()
     *   t = datetime.now()
     *   droid.eventPost('Some Event', t)
     * </pre>
     */
    @Rpc(description = "Post an event to the event queue.")
    public void eventPost(
            @RpcParameter(name = "name", description = "Name of event") String name,
            @RpcParameter(name = "data", description = "Data contained in event.") String data,
            @RpcParameter(name = "enqueue",
                    description = "Set to False if you don't want your events to be added to the event queue, just dispatched.") @RpcOptional @RpcDefault("false") Boolean enqueue) {
        postEvent(name, data, enqueue.booleanValue());
    }

    /**
     * Post an event and queue it
     */
    public void postEvent(String name, Object data) {
        postEvent(name, data, true);
    }

    /**
     * Posts an event with to the event queue.
     */
    public void postEvent(String name, Object data, boolean enqueue) {
        Event event = new Event(name, data);
        if (enqueue != false) {
            synchronized (mEventQueue) {
                while (mEventQueue.size() >= MAX_QUEUE_SIZE) {
                    mEventQueue.remove();
                }
                mEventQueue.add(event);
            }
            Log.v(String.format("postEvent(%s)", name));
        }
        synchronized (mNamedEventObservers) {
            for (EventObserver observer : mNamedEventObservers.get(name)) {
                observer.onEventReceived(event);
            }
        }
        synchronized (mGlobalEventObservers) {
            // TODO(navtej) Remove log.
            Log.v(String.format("mGlobalEventObservers size (%s)", mGlobalEventObservers.size()));
            for (EventObserver observer : mGlobalEventObservers) {
                observer.onEventReceived(event);
            }
        }
    }

    @RpcDeprecated(value = "eventPost", release = "r4")
    @Rpc(description = "Post an event to the event queue.")
    @RpcName(name = "postEvent")
    public void rpcPostEvent(
            @RpcParameter(name = "name") String name,
            @RpcParameter(name = "data") String data) {
        postEvent(name, data);
    }

    @RpcDeprecated(value = "eventPoll", release = "r4")
    @Rpc(description = "Returns and removes the oldest event (i.e. location or sensor update, etc.) from the event buffer.",
            returns = "Map of event properties.")
    public Event receiveEvent() {
        return mEventQueue.poll();
    }

    @RpcDeprecated(value = "eventWaitFor", release = "r4")
    @Rpc(description = "Blocks until an event with the supplied name occurs. Event is removed from the buffer if removeEvent is True.",
            returns = "Map of event properties.")
    public Event waitForEvent(
            @RpcParameter(name = "eventName")
            final String eventName,
            @RpcOptional
            final Boolean removeEvent,
            @RpcParameter(name = "timeout", description = "the maximum time to wait") @RpcOptional Integer timeout)
            throws InterruptedException {
        return eventWaitFor(eventName, removeEvent, timeout);
    }

    @Rpc(description = "Opens up a socket where you can read for events posted")
    public int startEventDispatcher(
            @RpcParameter(name = "port", description = "Port to use") @RpcDefault("0") @RpcOptional() Integer port) {
        if (mEventServer == null) {
            if (port == null) {
                port = 0;
            }
            mEventServer = new EventServer(port);
            addGlobalEventObserver(mEventServer);
            bEventServerRunning = true;
        }
        return mEventServer.getAddress().getPort();
    }

    @Rpc(description = "sl4a session is shutting down, send terminate event to client.")
    public void closeSl4aSession() {
        eventClearBuffer();
        postEvent("EventDispatcherShutdown", null);
    }

    @Rpc(description = "Stops the event server, you can't read in the port anymore")
    public void stopEventDispatcher() throws RuntimeException {
        if (bEventServerRunning == true) {
            if (mEventServer == null) {
                throw new RuntimeException("Not running");
            }
            bEventServerRunning = false;
            mEventServer.shutdown();
            Log.v(String.format("stopEventDispatcher   (%s)", mEventServer));
            removeEventObserver(mEventServer);
            mEventServer = null;
        }
        return;
    }

    @Override
    public void shutdown() {

        try {
            stopEventDispatcher();
        } catch (Exception e) {
            Log.e("Exception tearing down event dispatcher", e);
        }
        mGlobalEventObservers.clear();
        mEventQueue.clear();
    }

    public void addNamedEventObserver(String eventName, EventObserver observer) {
        mNamedEventObservers.put(eventName, observer);
    }

    public void addGlobalEventObserver(EventObserver observer) {
        mGlobalEventObservers.add(observer);
    }

    public void removeEventObserver(EventObserver observer) {
        mNamedEventObservers.removeAll(observer);
        mGlobalEventObservers.remove(observer);
    }

    public class BroadcastListener extends android.content.BroadcastReceiver {
        private EventFacade mParent;
        private boolean mEnQueue;

        public BroadcastListener(EventFacade parent, boolean enqueue) {
            mParent = parent;
            mEnQueue = enqueue;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle data;
            if (intent.getExtras() != null) {
                data = (Bundle) intent.getExtras().clone();
            } else {
                data = new Bundle();
            }
            data.putString("action", intent.getAction());
            try {
                mParent.eventPost("sl4a", JsonBuilder.build(data).toString(), mEnQueue);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

    }
}
