/*
 * Copyright (C) 2014 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.hardware.camera2.legacy;

import android.hardware.ICameraService;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.CaptureResultExtras;
import android.hardware.camera2.impl.PhysicalCaptureResultInfo;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.utils.SubmitInfo;
import android.os.ConditionVariable;
import android.os.IBinder;
import android.os.Looper;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.SparseArray;
import android.view.Surface;

import java.util.ArrayList;
import java.util.List;

import static android.system.OsConstants.EACCES;
import static android.system.OsConstants.ENODEV;

/**
 * Compatibility implementation of the Camera2 API binder interface.
 *
 * <p>
 * This is intended to be called from the same process as client
 * {@link android.hardware.camera2.CameraDevice}, and wraps a
 * {@link android.hardware.camera2.legacy.LegacyCameraDevice} that emulates Camera2 service using
 * the Camera1 API.
 * </p>
 *
 * <p>
 * Keep up to date with ICameraDeviceUser.aidl.
 * </p>
 */
@SuppressWarnings("deprecation")
public class CameraDeviceUserShim implements ICameraDeviceUser {
    private static final String TAG = "CameraDeviceUserShim";

    private static final boolean DEBUG = false;
    private static final int OPEN_CAMERA_TIMEOUT_MS = 5000; // 5 sec (same as api1 cts timeout)

    private final LegacyCameraDevice mLegacyDevice;

    private final Object mConfigureLock = new Object();
    private int mSurfaceIdCounter;
    private boolean mConfiguring;
    private final SparseArray<Surface> mSurfaces;
    private final CameraCharacteristics mCameraCharacteristics;
    private final CameraLooper mCameraInit;
    private final CameraCallbackThread mCameraCallbacks;


    protected CameraDeviceUserShim(int cameraId, LegacyCameraDevice legacyCamera,
            CameraCharacteristics characteristics, CameraLooper cameraInit,
            CameraCallbackThread cameraCallbacks) {
        mLegacyDevice = legacyCamera;
        mConfiguring = false;
        mSurfaces = new SparseArray<Surface>();
        mCameraCharacteristics = characteristics;
        mCameraInit = cameraInit;
        mCameraCallbacks = cameraCallbacks;

        mSurfaceIdCounter = 0;
    }

    private static int translateErrorsFromCamera1(int errorCode) {
        if (errorCode == -EACCES) {
            return ICameraService.ERROR_PERMISSION_DENIED;
        }

        return errorCode;
    }

    /**
     * Create a separate looper/thread for the camera to run on; open the camera.
     *
     * <p>Since the camera automatically latches on to the current thread's looper,
     * it's important that we have our own thread with our own looper to guarantee
     * that the camera callbacks get correctly posted to our own thread.</p>
     */
    private static class CameraLooper implements Runnable, AutoCloseable {
        private final int mCameraId;
        private Looper mLooper;
        private volatile int mInitErrors;
        private final Camera mCamera = Camera.openUninitialized();
        private final ConditionVariable mStartDone = new ConditionVariable();
        private final Thread mThread;

        /**
         * Spin up a new thread, immediately open the camera in the background.
         *
         * <p>Use {@link #waitForOpen} to block until the camera is finished opening.</p>
         *
         * @param cameraId numeric camera Id
         *
         * @see #waitForOpen
         */
        public CameraLooper(int cameraId) {
            mCameraId = cameraId;

            mThread = new Thread(this);
            mThread.start();
        }

        public Camera getCamera() {
            return mCamera;
        }

        @Override
        public void run() {
            // Set up a looper to be used by camera.
            Looper.prepare();

            // Save the looper so that we can terminate this thread
            // after we are done with it.
            mLooper = Looper.myLooper();
            mInitErrors = mCamera.cameraInitUnspecified(mCameraId);
            mStartDone.open();
            Looper.loop();  // Blocks forever until #close is called.
        }

        /**
         * Quit the looper safely; then join until the thread shuts down.
         */
        @Override
        public void close() {
            if (mLooper == null) {
                return;
            }

            mLooper.quitSafely();
            try {
                mThread.join();
            } catch (InterruptedException e) {
                throw new AssertionError(e);
            }

            mLooper = null;
        }

        /**
         * Block until the camera opens; then return its initialization error code (if any).
         *
         * @param timeoutMs timeout in milliseconds
         *
         * @return int error code
         *
         * @throws ServiceSpecificException if the camera open times out with ({@code CAMERA_ERROR})
         */
        public int waitForOpen(int timeoutMs) {
            // Block until the camera is open asynchronously
            if (!mStartDone.block(timeoutMs)) {
                Log.e(TAG, "waitForOpen - Camera failed to open after timeout of "
                        + OPEN_CAMERA_TIMEOUT_MS + " ms");
                try {
                    mCamera.release();
                } catch (RuntimeException e) {
                    Log.e(TAG, "connectBinderShim - Failed to release camera after timeout ", e);
                }

                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION);
            }

            return mInitErrors;
        }
    }

    /**
     * A thread to process callbacks to send back to the camera client.
     *
     * <p>This effectively emulates one-way binder semantics when in the same process as the
     * callee.</p>
     */
    private static class CameraCallbackThread implements ICameraDeviceCallbacks {
        private static final int CAMERA_ERROR = 0;
        private static final int CAMERA_IDLE = 1;
        private static final int CAPTURE_STARTED = 2;
        private static final int RESULT_RECEIVED = 3;
        private static final int PREPARED = 4;
        private static final int REPEATING_REQUEST_ERROR = 5;
        private static final int REQUEST_QUEUE_EMPTY = 6;

        private final HandlerThread mHandlerThread;
        private Handler mHandler;

        private final ICameraDeviceCallbacks mCallbacks;

        public CameraCallbackThread(ICameraDeviceCallbacks callbacks) {
            mCallbacks = callbacks;

            mHandlerThread = new HandlerThread("LegacyCameraCallback");
            mHandlerThread.start();
        }

        public void close() {
            mHandlerThread.quitSafely();
        }

        @Override
        public void onDeviceError(final int errorCode, final CaptureResultExtras resultExtras) {
            Message msg = getHandler().obtainMessage(CAMERA_ERROR,
                /*arg1*/ errorCode, /*arg2*/ 0,
                /*obj*/ resultExtras);
            getHandler().sendMessage(msg);
        }

        @Override
        public void onDeviceIdle() {
            Message msg = getHandler().obtainMessage(CAMERA_IDLE);
            getHandler().sendMessage(msg);
        }

        @Override
        public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) {
            Message msg = getHandler().obtainMessage(CAPTURE_STARTED,
                    /*arg1*/ (int) (timestamp & 0xFFFFFFFFL),
                    /*arg2*/ (int) ( (timestamp >> 32) & 0xFFFFFFFFL),
                    /*obj*/ resultExtras);
            getHandler().sendMessage(msg);
        }

        @Override
        public void onResultReceived(final CameraMetadataNative result,
                final CaptureResultExtras resultExtras,
                PhysicalCaptureResultInfo physicalResults[]) {
            Object[] resultArray = new Object[] { result, resultExtras };
            Message msg = getHandler().obtainMessage(RESULT_RECEIVED,
                    /*obj*/ resultArray);
            getHandler().sendMessage(msg);
        }

        @Override
        public void onPrepared(int streamId) {
            Message msg = getHandler().obtainMessage(PREPARED,
                    /*arg1*/ streamId, /*arg2*/ 0);
            getHandler().sendMessage(msg);
        }

        @Override
        public void onRepeatingRequestError(long lastFrameNumber, int repeatingRequestId) {
            Object[] objArray = new Object[] { lastFrameNumber, repeatingRequestId };
            Message msg = getHandler().obtainMessage(REPEATING_REQUEST_ERROR,
                    /*obj*/ objArray);
            getHandler().sendMessage(msg);
        }

        @Override
        public void onRequestQueueEmpty() {
            Message msg = getHandler().obtainMessage(REQUEST_QUEUE_EMPTY,
                    /* arg1 */ 0, /* arg2 */ 0);
            getHandler().sendMessage(msg);
        }

        @Override
        public IBinder asBinder() {
            // This is solely intended to be used for in-process binding.
            return null;
        }

        private Handler getHandler() {
            if (mHandler == null) {
                mHandler = new CallbackHandler(mHandlerThread.getLooper());
            }
            return mHandler;
        }

        private class CallbackHandler extends Handler {
            public CallbackHandler(Looper l) {
                super(l);
            }

            @Override
            public void handleMessage(Message msg) {
                try {
                    switch (msg.what) {
                        case CAMERA_ERROR: {
                            int errorCode = msg.arg1;
                            CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj;
                            mCallbacks.onDeviceError(errorCode, resultExtras);
                            break;
                        }
                        case CAMERA_IDLE:
                            mCallbacks.onDeviceIdle();
                            break;
                        case CAPTURE_STARTED: {
                            long timestamp = msg.arg2 & 0xFFFFFFFFL;
                            timestamp = (timestamp << 32) | (msg.arg1 & 0xFFFFFFFFL);
                            CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj;
                            mCallbacks.onCaptureStarted(resultExtras, timestamp);
                            break;
                        }
                        case RESULT_RECEIVED: {
                            Object[] resultArray = (Object[]) msg.obj;
                            CameraMetadataNative result = (CameraMetadataNative) resultArray[0];
                            CaptureResultExtras resultExtras = (CaptureResultExtras) resultArray[1];
                            mCallbacks.onResultReceived(result, resultExtras,
                                    new PhysicalCaptureResultInfo[0]);
                            break;
                        }
                        case PREPARED: {
                            int streamId = msg.arg1;
                            mCallbacks.onPrepared(streamId);
                            break;
                        }
                        case REPEATING_REQUEST_ERROR: {
                            Object[] objArray = (Object[]) msg.obj;
                            long lastFrameNumber = (Long) objArray[0];
                            int repeatingRequestId = (Integer) objArray[1];
                            mCallbacks.onRepeatingRequestError(lastFrameNumber, repeatingRequestId);
                            break;
                        }
                        case REQUEST_QUEUE_EMPTY: {
                            mCallbacks.onRequestQueueEmpty();
                            break;
                        }
                        default:
                            throw new IllegalArgumentException(
                                "Unknown callback message " + msg.what);
                    }
                } catch (RemoteException e) {
                    throw new IllegalStateException(
                        "Received remote exception during camera callback " + msg.what, e);
                }
            }
        }
    }

    public static CameraDeviceUserShim connectBinderShim(ICameraDeviceCallbacks callbacks,
                                                         int cameraId) {
        if (DEBUG) {
            Log.d(TAG, "Opening shim Camera device");
        }

        /*
         * Put the camera open on a separate thread with its own looper; otherwise
         * if the main thread is used then the callbacks might never get delivered
         * (e.g. in CTS which run its own default looper only after tests)
         */

        CameraLooper init = new CameraLooper(cameraId);

        CameraCallbackThread threadCallbacks = new CameraCallbackThread(callbacks);

        // TODO: Make this async instead of blocking
        int initErrors = init.waitForOpen(OPEN_CAMERA_TIMEOUT_MS);
        Camera legacyCamera = init.getCamera();

        // Check errors old HAL initialization
        LegacyExceptionUtils.throwOnServiceError(initErrors);

        // Disable shutter sounds (this will work unconditionally) for api2 clients
        legacyCamera.disableShutterSound();

        CameraInfo info = new CameraInfo();
        Camera.getCameraInfo(cameraId, info);

        Camera.Parameters legacyParameters = null;
        try {
            legacyParameters = legacyCamera.getParameters();
        } catch (RuntimeException e) {
            throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION,
                    "Unable to get initial parameters: " + e.getMessage());
        }

        CameraCharacteristics characteristics =
                LegacyMetadataMapper.createCharacteristics(legacyParameters, info);
        LegacyCameraDevice device = new LegacyCameraDevice(
                cameraId, legacyCamera, characteristics, threadCallbacks);
        return new CameraDeviceUserShim(cameraId, device, characteristics, init, threadCallbacks);
    }

    @Override
    public void disconnect() {
        if (DEBUG) {
            Log.d(TAG, "disconnect called.");
        }

        if (mLegacyDevice.isClosed()) {
            Log.w(TAG, "Cannot disconnect, device has already been closed.");
        }

        try {
            mLegacyDevice.close();
        } finally {
            mCameraInit.close();
            mCameraCallbacks.close();
        }
    }

    @Override
    public SubmitInfo submitRequest(CaptureRequest request, boolean streaming) {
        if (DEBUG) {
            Log.d(TAG, "submitRequest called.");
        }
        if (mLegacyDevice.isClosed()) {
            String err = "Cannot submit request, device has been closed.";
            Log.e(TAG, err);
            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
        }

        synchronized(mConfigureLock) {
            if (mConfiguring) {
                String err = "Cannot submit request, configuration change in progress.";
                Log.e(TAG, err);
                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
            }
        }
        return mLegacyDevice.submitRequest(request, streaming);
    }

    @Override
    public SubmitInfo submitRequestList(CaptureRequest[] request, boolean streaming) {
        if (DEBUG) {
            Log.d(TAG, "submitRequestList called.");
        }
        if (mLegacyDevice.isClosed()) {
            String err = "Cannot submit request list, device has been closed.";
            Log.e(TAG, err);
            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
        }

        synchronized(mConfigureLock) {
            if (mConfiguring) {
                String err = "Cannot submit request, configuration change in progress.";
                Log.e(TAG, err);
                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
            }
        }
        return mLegacyDevice.submitRequestList(request, streaming);
    }

    @Override
    public long cancelRequest(int requestId) {
        if (DEBUG) {
            Log.d(TAG, "cancelRequest called.");
        }
        if (mLegacyDevice.isClosed()) {
            String err = "Cannot cancel request, device has been closed.";
            Log.e(TAG, err);
            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
        }

        synchronized(mConfigureLock) {
            if (mConfiguring) {
                String err = "Cannot cancel request, configuration change in progress.";
                Log.e(TAG, err);
                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
            }
        }
        return mLegacyDevice.cancelRequest(requestId);
    }

    @Override
    public void beginConfigure() {
        if (DEBUG) {
            Log.d(TAG, "beginConfigure called.");
        }
        if (mLegacyDevice.isClosed()) {
            String err = "Cannot begin configure, device has been closed.";
            Log.e(TAG, err);
            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
        }

        synchronized(mConfigureLock) {
            if (mConfiguring) {
                String err = "Cannot begin configure, configuration change already in progress.";
                Log.e(TAG, err);
                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
            }
            mConfiguring = true;
        }
    }

    @Override
    public void endConfigure(int operatingMode, CameraMetadataNative sessionParams) {
        if (DEBUG) {
            Log.d(TAG, "endConfigure called.");
        }
        if (mLegacyDevice.isClosed()) {
            String err = "Cannot end configure, device has been closed.";
            Log.e(TAG, err);
            synchronized(mConfigureLock) {
                mConfiguring = false;
            }
            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
        }

        if (operatingMode != ICameraDeviceUser.NORMAL_MODE) {
            String err = "LEGACY devices do not support this operating mode";
            Log.e(TAG, err);
            synchronized(mConfigureLock) {
                mConfiguring = false;
            }
            throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
        }

        SparseArray<Surface> surfaces = null;
        synchronized(mConfigureLock) {
            if (!mConfiguring) {
                String err = "Cannot end configure, no configuration change in progress.";
                Log.e(TAG, err);
                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
            }
            if (mSurfaces != null) {
                surfaces = mSurfaces.clone();
            }
            mConfiguring = false;
        }
        mLegacyDevice.configureOutputs(surfaces);
    }

    @Override
    public void deleteStream(int streamId) {
        if (DEBUG) {
            Log.d(TAG, "deleteStream called.");
        }
        if (mLegacyDevice.isClosed()) {
            String err = "Cannot delete stream, device has been closed.";
            Log.e(TAG, err);
            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
        }

        synchronized(mConfigureLock) {
            if (!mConfiguring) {
                String err = "Cannot delete stream, no configuration change in progress.";
                Log.e(TAG, err);
                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
            }
            int index = mSurfaces.indexOfKey(streamId);
            if (index < 0) {
                String err = "Cannot delete stream, stream id " + streamId + " doesn't exist.";
                Log.e(TAG, err);
                throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
            }
            mSurfaces.removeAt(index);
        }
    }

    @Override
    public int createStream(OutputConfiguration outputConfiguration) {
        if (DEBUG) {
            Log.d(TAG, "createStream called.");
        }
        if (mLegacyDevice.isClosed()) {
            String err = "Cannot create stream, device has been closed.";
            Log.e(TAG, err);
            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
        }

        synchronized(mConfigureLock) {
            if (!mConfiguring) {
                String err = "Cannot create stream, beginConfigure hasn't been called yet.";
                Log.e(TAG, err);
                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
            }
            if (outputConfiguration.getRotation() != OutputConfiguration.ROTATION_0) {
                String err = "Cannot create stream, stream rotation is not supported.";
                Log.e(TAG, err);
                throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
            }
            int id = ++mSurfaceIdCounter;
            mSurfaces.put(id, outputConfiguration.getSurface());
            return id;
        }
    }

    @Override
    public void finalizeOutputConfigurations(int steamId, OutputConfiguration config) {
        String err = "Finalizing output configuration is not supported on legacy devices";
        Log.e(TAG, err);
        throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
    }

    @Override
    public int createInputStream(int width, int height, int format) {
        String err = "Creating input stream is not supported on legacy devices";
        Log.e(TAG, err);
        throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
    }

    @Override
    public Surface getInputSurface() {
        String err = "Getting input surface is not supported on legacy devices";
        Log.e(TAG, err);
        throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
    }

    @Override
    public CameraMetadataNative createDefaultRequest(int templateId) {
        if (DEBUG) {
            Log.d(TAG, "createDefaultRequest called.");
        }
        if (mLegacyDevice.isClosed()) {
            String err = "Cannot create default request, device has been closed.";
            Log.e(TAG, err);
            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
        }

        CameraMetadataNative template;
        try {
            template =
                    LegacyMetadataMapper.createRequestTemplate(mCameraCharacteristics, templateId);
        } catch (IllegalArgumentException e) {
            String err = "createDefaultRequest - invalid templateId specified";
            Log.e(TAG, err);
            throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
        }

        return template;
    }

    @Override
    public CameraMetadataNative getCameraInfo() {
        if (DEBUG) {
            Log.d(TAG, "getCameraInfo called.");
        }
        // TODO: implement getCameraInfo.
        Log.e(TAG, "getCameraInfo unimplemented.");
        return null;
    }

    @Override
    public void updateOutputConfiguration(int streamId, OutputConfiguration config) {
        // TODO: b/63912484 implement updateOutputConfiguration.
    }

    @Override
    public void waitUntilIdle() throws RemoteException {
        if (DEBUG) {
            Log.d(TAG, "waitUntilIdle called.");
        }
        if (mLegacyDevice.isClosed()) {
            String err = "Cannot wait until idle, device has been closed.";
            Log.e(TAG, err);
            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
        }

        synchronized(mConfigureLock) {
            if (mConfiguring) {
                String err = "Cannot wait until idle, configuration change in progress.";
                Log.e(TAG, err);
                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
            }
        }
        mLegacyDevice.waitUntilIdle();
    }

    @Override
    public long flush() {
        if (DEBUG) {
            Log.d(TAG, "flush called.");
        }
        if (mLegacyDevice.isClosed()) {
            String err = "Cannot flush, device has been closed.";
            Log.e(TAG, err);
            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
        }

        synchronized(mConfigureLock) {
            if (mConfiguring) {
                String err = "Cannot flush, configuration change in progress.";
                Log.e(TAG, err);
                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
            }
        }
        return mLegacyDevice.flush();
    }

    public void prepare(int streamId) {
        if (DEBUG) {
            Log.d(TAG, "prepare called.");
        }
        if (mLegacyDevice.isClosed()) {
            String err = "Cannot prepare stream, device has been closed.";
            Log.e(TAG, err);
            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
        }

        // LEGACY doesn't support actual prepare, just signal success right away
        mCameraCallbacks.onPrepared(streamId);
    }

    public void prepare2(int maxCount, int streamId) {
        // We don't support this in LEGACY mode.
        prepare(streamId);
    }

    public void tearDown(int streamId) {
        if (DEBUG) {
            Log.d(TAG, "tearDown called.");
        }
        if (mLegacyDevice.isClosed()) {
            String err = "Cannot tear down stream, device has been closed.";
            Log.e(TAG, err);
            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
        }

        // LEGACY doesn't support actual teardown, so just a no-op
    }

    @Override
    public IBinder asBinder() {
        // This is solely intended to be used for in-process binding.
        return null;
    }
}
