/*
 * Copyright (C) 2013 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.speech.hotword;

import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;

/**
 * This class provides a base class for hotword detection service implementations.
 * This class should be extended only if you wish to implement a new hotword recognizer.
 */
public abstract class HotwordRecognitionService extends Service {
    /**
     * The {@link Intent} that must be declared as handled by the service.
     */
    @SdkConstant(SdkConstantType.SERVICE_ACTION)
    public static final String SERVICE_INTERFACE =
            "android.speech.hotword.HotwordRecognitionService";

    /** Log messages identifier */
    private static final String TAG = "HotwordRecognitionService";

    /** Debugging flag */
    private static final boolean DBG = false;

    /**
     * Key used to retrieve a string to be displayed to the user.
     */
    public static final String KEY_PROMPT_TEXT = "prompt_text";

    /**
     * Event type used to indicate to the user that the prompt for
     * hotword recognition has changed.
     */
    public static final int EVENT_TYPE_PROMPT_CHANGED = 1;

    /** Audio recording error. */
    public static final int ERROR_AUDIO = 1;

    /** RecognitionService busy. */
    public static final int ERROR_RECOGNIZER_BUSY = 2;

    /** This indicates a permanent failure and the clients shouldn't retry on this */
    public static final int ERROR_FAILED = 3;

    /** Client-side errors */
    public static final int ERROR_CLIENT = 4;

    /** The service timed out */
    public static final int ERROR_TIMEOUT = 5;

    /** The service received concurrent start calls */
    public static final int ERROR_SERVICE_ALREADY_STARTED = 6;

    /** Hotword recognition is unavailable on the device */
    public static final int ERROR_UNAVAILABLE = 7;

    private static final int MSG_START_RECOGNITION = 1;
    private static final int MSG_STOP_RECOGNITION = 2;

    /**
     * The current callback of an application that invoked the
     * {@link HotwordRecognitionService#onStartHotwordRecognition(Callback)} method
     */
    private Callback mCurrentCallback = null;

    // Handle the client dying.
    private final IBinder.DeathRecipient mCallbackDeathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            if (DBG) Log.i(TAG, "HotwordRecognitionService listener died");
            mCurrentCallback = null;
        }
    };

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_START_RECOGNITION:
                    dispatchStartRecognition((IHotwordRecognitionListener) msg.obj);
                    break;
                case MSG_STOP_RECOGNITION:
                    dispatchStopRecognition((IHotwordRecognitionListener) msg.obj);
                    break;
            }
        }
    };

    /** Binder of the hotword recognition service */
    private RecognitionServiceBinder mBinder = new RecognitionServiceBinder(this);

    private void dispatchStartRecognition(IHotwordRecognitionListener listener) {
        if (mCurrentCallback == null) {
            if (DBG) Log.d(TAG, "created new mCurrentCallback, listener = " + listener.asBinder());
            try {
                listener.asBinder().linkToDeath(mCallbackDeathRecipient, 0);
            } catch (RemoteException e) {
                if (DBG) Log.d(TAG, "listener died before linkToDeath()");
            }
            mCurrentCallback = new Callback(listener);
            HotwordRecognitionService.this.onStartHotwordRecognition(mCurrentCallback);
        } else {
            try {
                listener.onHotwordError(ERROR_RECOGNIZER_BUSY);
            } catch (RemoteException e) {
                if (DBG) Log.d(TAG, "onError call from startRecognition failed");
            }
            if (DBG) Log.d(TAG, "concurrent startRecognition received - ignoring this call");
        }
    }

    private void dispatchStopRecognition(IHotwordRecognitionListener listener) {
        try {
            if (mCurrentCallback == null) {
                listener.onHotwordError(ERROR_CLIENT);
                Log.w(TAG, "stopRecognition called with no preceding startRecognition - ignoring");
            } else if (mCurrentCallback.mListener.asBinder() != listener.asBinder()) {
                listener.onHotwordError(ERROR_RECOGNIZER_BUSY);
                Log.w(TAG, "stopRecognition called by a different caller - ignoring");
            } else { // the correct state
                mCurrentCallback.onHotwordRecognitionStopped();
                mCurrentCallback = null;
                HotwordRecognitionService.this.onStopHotwordRecognition();
            }
        } catch (RemoteException e) { // occurs if onError fails
            if (DBG) Log.d(TAG, "onError call from stopRecognition failed");
        }
    }

    @Override
    public IBinder onBind(final Intent intent) {
        if (DBG) Log.d(TAG, "onBind, intent=" + intent);
        return mBinder;
    }

    @Override
    public void onDestroy() {
        if (DBG) Log.d(TAG, "onDestroy");
        if (mCurrentCallback != null) {
            mCurrentCallback.mListener.asBinder().unlinkToDeath(mCallbackDeathRecipient, 0);
            mCurrentCallback = null;
        }
        mBinder.clearReference();
        super.onDestroy();
    }

    /**
     * Notifies the service to start a recognition.
     *
     * @param callback that receives the callbacks from the service.
     */
    public abstract void onStartHotwordRecognition(Callback callback);

    /**
     * Notifies the service to stop recognition.
     */
    public abstract void onStopHotwordRecognition();

    /** Binder of the hotword recognition service */
    private static class RecognitionServiceBinder extends IHotwordRecognitionService.Stub {
        private HotwordRecognitionService mInternalService;

        public RecognitionServiceBinder(HotwordRecognitionService service) {
            mInternalService = service;
        }

        public void startHotwordRecognition(IHotwordRecognitionListener listener) {
            if (DBG) Log.d(TAG, "startRecognition called by: " + listener.asBinder());
            if (mInternalService != null && mInternalService.checkPermissions(listener)) {
                mInternalService.mHandler.sendMessage(
                        Message.obtain(mInternalService.mHandler, MSG_START_RECOGNITION, listener));
            }
        }

        public void stopHotwordRecognition(IHotwordRecognitionListener listener) {
            if (DBG) Log.d(TAG, "stopRecognition called by: " + listener.asBinder());
            if (mInternalService != null && mInternalService.checkPermissions(listener)) {
                mInternalService.mHandler.sendMessage(
                        Message.obtain(mInternalService.mHandler, MSG_STOP_RECOGNITION, listener));
            }
        }

        private void clearReference() {
            mInternalService = null;
        }
    }

    /**
     * Checks whether the caller has sufficient permissions
     *
     * @param listener to send the error message to in case of error.
     * @return {@code true} if the caller has enough permissions, {@code false} otherwise.
     */
    private boolean checkPermissions(IHotwordRecognitionListener listener) {
        if (DBG) Log.d(TAG, "checkPermissions");
        if (checkCallingOrSelfPermission(android.Manifest.permission.HOTWORD_RECOGNITION) ==
                PackageManager.PERMISSION_GRANTED) {
            return true;
        }
        try {
            Log.e(TAG, "Recognition service called without HOTWORD_RECOGNITION permissions");
            listener.onHotwordError(ERROR_FAILED);
        } catch (RemoteException e) {
            Log.e(TAG, "onHotwordError(ERROR_FAILED) message failed", e);
        }
        return false;
    }

    /**
     * This class acts passes on the callbacks received from the Hotword service
     * to the listener.
     */
    public static class Callback {
        private final IHotwordRecognitionListener mListener;

        private Callback(IHotwordRecognitionListener listener) {
            mListener = listener;
        }

        /**
         * Called when the service starts listening for hotword.
         */
        public void onHotwordRecognitionStarted() throws RemoteException {
            mListener.onHotwordRecognitionStarted();
        }

        /**
         * Called when the service starts listening for hotword.
         */
        public void onHotwordRecognitionStopped() throws RemoteException {
            mListener.onHotwordRecognitionStopped();
        }

        /**
         * Called on an event of interest to the client.
         *
         * @param eventType the event type.
         * @param eventBundle a Bundle containing the hotword event(s).
         */
        public void onHotwordEvent(int eventType, Bundle eventBundle) throws RemoteException {
            mListener.onHotwordEvent(eventType, eventBundle);
        }

        /**
         * Called back when hotword is detected.
         *
         * @param activityIntent for the activity to launch, post hotword detection.
         */
        public void onHotwordRecognized(Intent activityIntent) throws RemoteException {
            mListener.onHotwordRecognized(activityIntent);
        }

        /**
         * Called when the HotwordRecognitionService encounters an error.
         *
         * @param errorCode the error code describing the error that was encountered.
         */
        public void onError(int errorCode) throws RemoteException {
            mListener.onHotwordError(errorCode);
        }
    }
}
