/*
 * Copyright (C) 2015 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 android.car;

import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

/**
 * CarAppContextManager allows applications to set and listen for the current application context
 * like active navigation or active voice command. Usually only one instance of such application
 * should run in the system, and other app setting the flag for the matching app should
 * lead into other app to stop.
 */
public class CarAppContextManager implements CarManagerBase {
    /**
     * Listener to get notification for app getting information on app context change.
     */
    public interface AppContextChangeListener {
        /**
         * Application context has changed. Note that {@link CarAppContextManager} instance
         * causing the change will not get this notification.
         * @param activeContexts
         */
        void onAppContextChange(int activeContexts);
    }

    /**
     * Listener to get notification for app getting information on app context ownership loss.
     */
    public interface AppContextOwnershipChangeListener {
        /**
         * Lost ownership for the context, which happens when other app has set the context.
         * The app losing context should stop the action associated with the context.
         * For example, navigaiton app currently running active navigation should stop navigation
         * upon getting this for {@link CarAppContextManager#APP_CONTEXT_NAVIGATION}.
         * @param context
         */
        void onAppContextOwnershipLoss(int context);
    }

    /** @hide */
    public static final int APP_CONTEXT_START_FLAG = 0x1;
    /**
     * Flag for active navigation.
     */
    public static final int APP_CONTEXT_NAVIGATION = 0x1;
    /**
     * Flag for active voice command.
     */
    public static final int APP_CONTEXT_VOICE_COMMAND = 0x2;
    /**
     * Update this after adding a new flag.
     * @hide
     */
    public static final int APP_CONTEXT_END_FLAG = 0x2;

    private final IAppContext mService;
    private final Handler mHandler;
    private final IAppContextListenerImpl mBinderListener;
    private final Map<Integer, AppContextOwnershipChangeListener> mOwnershipListeners;

    private AppContextChangeListener mListener;
    private int mContextFilter;

    /**
     * @hide
     */
    CarAppContextManager(IBinder service, Looper looper) {
        mService = IAppContext.Stub.asInterface(service);
        mHandler = new Handler(looper);
        mBinderListener = new IAppContextListenerImpl(this);
        mOwnershipListeners = new HashMap<Integer, AppContextOwnershipChangeListener>();
    }

    /**
     * Register listener to monitor app context change. Only one listener can be registered and
     * registering multiple times will lead into only the last listener to be active.
     * @param listener
     * @param contextFilter Flags of cotexts to get notification.
     * @throws CarNotConnectedException
     */
    public void registerContextListener(AppContextChangeListener listener, int contextFilter)
            throws CarNotConnectedException {
        if (listener == null) {
            throw new IllegalArgumentException("null listener");
        }
        synchronized(this) {
            if (mListener == null || mContextFilter != contextFilter) {
                try {
                    mService.registerContextListener(mBinderListener, contextFilter);
                } catch (RemoteException e) {
                    throw new CarNotConnectedException(e);
                }
            }
            mListener = listener;
            mContextFilter = contextFilter;
        }
    }

    /**
     * Unregister listener and stop listening context change events. If app has owned a context
     * by {@link #setActiveContext(int)}, it will be reset to inactive state.
     * @throws CarNotConnectedException
     */
    public void unregisterContextListener() throws CarNotConnectedException {
        synchronized(this) {
            try {
                mService.unregisterContextListener(mBinderListener);
            } catch (RemoteException e) {
                throw new CarNotConnectedException(e);
            }
            mListener = null;
            mContextFilter = 0;
        }
    }

    public int getActiveAppContexts() throws CarNotConnectedException {
        try {
            return mService.getActiveAppContexts();
        } catch (RemoteException e) {
            throw new CarNotConnectedException(e);
        }
    }

    public boolean isOwningContext(int context) throws CarNotConnectedException {
        try {
            return mService.isOwningContext(mBinderListener, context);
        } catch (RemoteException e) {
            throw new CarNotConnectedException(e);
        }
    }

    /**
     * Set the given contexts as active. By setting this, the application is becoming owner
     * of the context, and will get
     * {@link AppContextOwnershipChangeListener#onAppContextOwnershipLoss(int)}
     * if ownership is given to other app by calling this. Fore-ground app will have higher priority
     * and other app cannot set the same context while owner is in fore-ground.
     * Only one listener per context can be registered and
     * registering multiple times will lead into only the last listener to be active.
     * @param ownershipListener
     * @param contexts
     * @throws CarNotConnectedException
     * @throws SecurityException If owner cannot be changed.
     */
    public void setActiveContexts(AppContextOwnershipChangeListener ownershipListener, int contexts)
            throws SecurityException, CarNotConnectedException {
        if (ownershipListener == null) {
            throw new IllegalArgumentException("null listener");
        }
        synchronized (this) {
            try {
                mService.setActiveContexts(mBinderListener, contexts);
            } catch (RemoteException e) {
                throw new CarNotConnectedException(e);
            }
            for (int flag = APP_CONTEXT_START_FLAG; flag <= APP_CONTEXT_END_FLAG; flag <<= 1) {
                if ((flag & contexts) != 0) {
                    mOwnershipListeners.put(flag, ownershipListener);
                }
            }
        }
    }

    /**
     * Reset the given contexts, i.e. mark them as inactive. This also involves releasing ownership
     * for the context.
     * @param contexts
     * @throws CarNotConnectedException
     */
    public void resetActiveContexts(int contexts) throws CarNotConnectedException {
        try {
            mService.resetActiveContexts(mBinderListener, contexts);
        } catch (RemoteException e) {
            throw new CarNotConnectedException(e);
        }
        synchronized (this) {
            for (int flag = APP_CONTEXT_START_FLAG; flag <= APP_CONTEXT_END_FLAG; flag <<= 1) {
                if ((flag & contexts) != 0) {
                    mOwnershipListeners.remove(flag);
                }
            }
        }
    }

    @Override
    public void onCarDisconnected() {
        // nothing to do
    }

    private void handleAppContextChange(int activeContexts) {
        AppContextChangeListener listener;
        int newContext;
        synchronized (this) {
            if (mListener == null) {
                return;
            }
            listener = mListener;
            newContext = activeContexts & mContextFilter;
        }
        listener.onAppContextChange(newContext);
    }

    private void handleAppContextOwnershipLoss(int context) {
        AppContextOwnershipChangeListener listener;
        synchronized (this) {
            listener = mOwnershipListeners.get(context);
            if (listener == null) {
                return;
            }
        }
        listener.onAppContextOwnershipLoss(context);
    }

    private static class IAppContextListenerImpl extends IAppContextListener.Stub {

        private final WeakReference<CarAppContextManager> mManager;

        private IAppContextListenerImpl(CarAppContextManager manager) {
            mManager = new WeakReference<>(manager);
        }

        @Override
        public void onAppContextChange(final int activeContexts) {
            final CarAppContextManager manager = mManager.get();
            if (manager == null) {
                return;
            }
            manager.mHandler.post(new Runnable() {
                @Override
                public void run() {
                    manager.handleAppContextChange(activeContexts);
                }
            });
        }

        @Override
        public void onAppContextOwnershipLoss(final int context) {
            final CarAppContextManager manager = mManager.get();
            if (manager == null) {
                return;
            }
            manager.mHandler.post(new Runnable() {
                @Override
                public void run() {
                    manager.handleAppContextOwnershipLoss(context);
                }
            });
        }
    }
}
