/*
 * Copyright (C) 2012 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.
 */

#ifndef ANDROID_SERVERS_CAMERA_CAMERA2DEVICE_H
#define ANDROID_SERVERS_CAMERA_CAMERA2DEVICE_H

#include <utils/Condition.h>
#include <utils/Errors.h>
#include <utils/List.h>
#include <utils/Mutex.h>

#include "common/CameraDeviceBase.h"

namespace android {

/**
 * CameraDevice for HAL devices with version CAMERA_DEVICE_API_VERSION_2_0
 *
 * TODO for camera2 API implementation:
 * Does not produce notifyShutter / notifyIdle callbacks to NotificationListener
 * Use waitUntilDrained for idle.
 */
class Camera2Device: public CameraDeviceBase {
  public:
    Camera2Device(int id);

    virtual ~Camera2Device();

    /**
     * CameraDevice interface
     */
    virtual int      getId() const;
    virtual status_t initialize(CameraModule *module);
    virtual status_t disconnect();
    virtual status_t dump(int fd, const Vector<String16>& args);
    virtual const CameraMetadata& info() const;
    virtual status_t capture(CameraMetadata &request, int64_t *lastFrameNumber = NULL);
    virtual status_t captureList(const List<const CameraMetadata> &requests,
                                 int64_t *lastFrameNumber = NULL);
    virtual status_t setStreamingRequest(const CameraMetadata &request,
                                         int64_t *lastFrameNumber = NULL);
    virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests,
                                             int64_t *lastFrameNumber = NULL);
    virtual status_t clearStreamingRequest(int64_t *lastFrameNumber = NULL);
    virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout);
    virtual status_t createStream(sp<Surface> consumer,
            uint32_t width, uint32_t height, int format,
            android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id);
    virtual status_t createInputStream(
            uint32_t width, uint32_t height, int format, int *id);
    virtual status_t createReprocessStreamFromStream(int outputId, int *id);
    virtual status_t getStreamInfo(int id,
            uint32_t *width, uint32_t *height,
            uint32_t *format, android_dataspace *dataSpace);
    virtual status_t setStreamTransform(int id, int transform);
    virtual status_t deleteStream(int id);
    virtual status_t deleteReprocessStream(int id);
    // No-op on HAL2 devices
    virtual status_t configureStreams(bool isConstrainedHighSpeed = false);
    virtual status_t getInputBufferProducer(
            sp<IGraphicBufferProducer> *producer);
    virtual status_t createDefaultRequest(int templateId, CameraMetadata *request);
    virtual status_t waitUntilDrained();
    virtual status_t setNotifyCallback(NotificationListener *listener);
    virtual bool     willNotify3A();
    virtual status_t waitForNextFrame(nsecs_t timeout);
    virtual status_t getNextResult(CaptureResult *frame);
    virtual status_t triggerAutofocus(uint32_t id);
    virtual status_t triggerCancelAutofocus(uint32_t id);
    virtual status_t triggerPrecaptureMetering(uint32_t id);
    virtual status_t pushReprocessBuffer(int reprocessStreamId,
            buffer_handle_t *buffer, wp<BufferReleasedListener> listener);
    // Flush implemented as just a wait
    virtual status_t flush(int64_t *lastFrameNumber = NULL);
    // Prepare and tearDown are no-ops
    virtual status_t prepare(int streamId);
    virtual status_t tearDown(int streamId);

    virtual uint32_t getDeviceVersion();
    virtual ssize_t getJpegBufferSize(uint32_t width, uint32_t height) const;

  private:
    const int mId;
    camera2_device_t *mHal2Device;

    CameraMetadata mDeviceInfo;

    uint32_t mDeviceVersion;

    /**
     * Queue class for both sending requests to a camera2 device, and for
     * receiving frames from a camera2 device.
     */
    class MetadataQueue: public camera2_request_queue_src_ops_t,
                         public camera2_frame_queue_dst_ops_t {
      public:
        MetadataQueue();
        ~MetadataQueue();

        // Interface to camera2 HAL device, either for requests (device is
        // consumer) or for frames (device is producer)
        const camera2_request_queue_src_ops_t*   getToConsumerInterface();
        void setFromConsumerInterface(camera2_device_t *d);

        // Connect queue consumer endpoint to a camera2 device
        status_t setConsumerDevice(camera2_device_t *d);
        // Connect queue producer endpoint to a camera2 device
        status_t setProducerDevice(camera2_device_t *d);

        const camera2_frame_queue_dst_ops_t* getToProducerInterface();

        // Real interfaces. On enqueue, queue takes ownership of buffer pointer
        // On dequeue, user takes ownership of buffer pointer.
        status_t enqueue(camera_metadata_t *buf);
        status_t dequeue(camera_metadata_t **buf, bool incrementCount = false);
        int      getBufferCount();
        status_t waitForBuffer(nsecs_t timeout);
        // Wait until a buffer with the given ID is dequeued. Will return
        // immediately if the latest buffer dequeued has that ID.
        status_t waitForDequeue(int32_t id, nsecs_t timeout);

        // Set repeating buffer(s); if the queue is empty on a dequeue call, the
        // queue copies the contents of the stream slot into the queue, and then
        // dequeues the first new entry. The methods take the ownership of the
        // metadata buffers passed in.
        status_t setStreamSlot(camera_metadata_t *buf);
        status_t setStreamSlot(const List<camera_metadata_t*> &bufs);

        // Clear the request queue and the streaming slot
        status_t clear();

        status_t dump(int fd, const Vector<String16>& args);

      private:
        status_t signalConsumerLocked();
        status_t freeBuffers(List<camera_metadata_t*>::iterator start,
                List<camera_metadata_t*>::iterator end);

        camera2_device_t *mHal2Device;

        Mutex mMutex;
        Condition notEmpty;

        int mFrameCount;
        int32_t mLatestRequestId;
        Condition mNewRequestId;

        int mCount;
        List<camera_metadata_t*> mEntries;
        int mStreamSlotCount;
        List<camera_metadata_t*> mStreamSlot;

        bool mSignalConsumer;

        static MetadataQueue* getInstance(
            const camera2_frame_queue_dst_ops_t *q);
        static MetadataQueue* getInstance(
            const camera2_request_queue_src_ops_t *q);

        static int consumer_buffer_count(
            const camera2_request_queue_src_ops_t *q);

        static int consumer_dequeue(const camera2_request_queue_src_ops_t *q,
            camera_metadata_t **buffer);

        static int consumer_free(const camera2_request_queue_src_ops_t *q,
                camera_metadata_t *old_buffer);

        static int producer_dequeue(const camera2_frame_queue_dst_ops_t *q,
                size_t entries, size_t bytes,
                camera_metadata_t **buffer);

        static int producer_cancel(const camera2_frame_queue_dst_ops_t *q,
            camera_metadata_t *old_buffer);

        static int producer_enqueue(const camera2_frame_queue_dst_ops_t *q,
                camera_metadata_t *filled_buffer);

    }; // class MetadataQueue

    MetadataQueue mRequestQueue;
    MetadataQueue mFrameQueue;

    /**
     * Adapter from an ANativeWindow interface to camera2 device stream ops.
     * Also takes care of allocating/deallocating stream in device interface
     */
    class StreamAdapter: public camera2_stream_ops, public virtual RefBase {
      public:
        StreamAdapter(camera2_device_t *d);

        ~StreamAdapter();

        /**
         * Create a HAL device stream of the requested size and format.
         *
         * If format is CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, then the HAL device
         * selects an appropriate format; it can be queried with getFormat.
         *
         * If format is HAL_PIXEL_FORMAT_COMPRESSED, the size parameter must
         * be equal to the size in bytes of the buffers to allocate for the
         * stream. For other formats, the size parameter is ignored.
         */
        status_t connectToDevice(sp<ANativeWindow> consumer,
                uint32_t width, uint32_t height, int format, size_t size);

        status_t release();

        status_t setTransform(int transform);

        // Get stream parameters.
        // Only valid after a successful connectToDevice call.
        int      getId() const     { return mId; }
        uint32_t getWidth() const  { return mWidth; }
        uint32_t getHeight() const { return mHeight; }
        uint32_t getFormat() const { return mFormat; }

        // Dump stream information
        status_t dump(int fd, const Vector<String16>& args);

      private:
        enum {
            ERROR = -1,
            RELEASED = 0,
            ALLOCATED,
            CONNECTED,
            ACTIVE
        } mState;

        sp<ANativeWindow> mConsumerInterface;
        camera2_device_t *mHal2Device;

        uint32_t mId;
        uint32_t mWidth;
        uint32_t mHeight;
        uint32_t mFormat;
        size_t   mSize;
        uint32_t mUsage;
        uint32_t mMaxProducerBuffers;
        uint32_t mMaxConsumerBuffers;
        uint32_t mTotalBuffers;
        int mFormatRequested;

        /** Debugging information */
        uint32_t mActiveBuffers;
        uint32_t mFrameCount;
        int64_t  mLastTimestamp;

        const camera2_stream_ops *getStreamOps();

        static ANativeWindow* toANW(const camera2_stream_ops_t *w);

        static int dequeue_buffer(const camera2_stream_ops_t *w,
                buffer_handle_t** buffer);

        static int enqueue_buffer(const camera2_stream_ops_t* w,
                int64_t timestamp,
                buffer_handle_t* buffer);

        static int cancel_buffer(const camera2_stream_ops_t* w,
                buffer_handle_t* buffer);

        static int set_crop(const camera2_stream_ops_t* w,
                int left, int top, int right, int bottom);
    }; // class StreamAdapter

    typedef List<sp<StreamAdapter> > StreamList;
    StreamList mStreams;

    /**
     * Adapter from an ANativeWindow interface to camera2 device stream ops.
     * Also takes care of allocating/deallocating stream in device interface
     */
    class ReprocessStreamAdapter: public camera2_stream_in_ops, public virtual RefBase {
      public:
        ReprocessStreamAdapter(camera2_device_t *d);

        ~ReprocessStreamAdapter();

        /**
         * Create a HAL device reprocess stream based on an existing output stream.
         */
        status_t connectToDevice(const sp<StreamAdapter> &outputStream);

        status_t release();

        /**
         * Push buffer into stream for reprocessing. Takes ownership until it notifies
         * that the buffer has been released
         */
        status_t pushIntoStream(buffer_handle_t *handle,
                const wp<BufferReleasedListener> &releaseListener);

        /**
         * Get stream parameters.
         * Only valid after a successful connectToDevice call.
         */
        int      getId() const     { return mId; }
        uint32_t getWidth() const  { return mWidth; }
        uint32_t getHeight() const { return mHeight; }
        uint32_t getFormat() const { return mFormat; }

        // Dump stream information
        status_t dump(int fd, const Vector<String16>& args);

      private:
        enum {
            ERROR = -1,
            RELEASED = 0,
            ACTIVE
        } mState;

        sp<ANativeWindow> mConsumerInterface;
        wp<StreamAdapter> mBaseStream;

        struct QueueEntry {
            buffer_handle_t *handle;
            wp<BufferReleasedListener> releaseListener;
        };

        List<QueueEntry> mQueue;

        List<QueueEntry> mInFlightQueue;

        camera2_device_t *mHal2Device;

        uint32_t mId;
        uint32_t mWidth;
        uint32_t mHeight;
        uint32_t mFormat;

        /** Debugging information */
        uint32_t mActiveBuffers;
        uint32_t mFrameCount;
        int64_t  mLastTimestamp;

        const camera2_stream_in_ops *getStreamOps();

        static int acquire_buffer(const camera2_stream_in_ops_t *w,
                buffer_handle_t** buffer);

        static int release_buffer(const camera2_stream_in_ops_t* w,
                buffer_handle_t* buffer);

    }; // class ReprocessStreamAdapter

    typedef List<sp<ReprocessStreamAdapter> > ReprocessStreamList;
    ReprocessStreamList mReprocessStreams;

    // Receives HAL notifications and routes them to the NotificationListener
    static void notificationCallback(int32_t msg_type,
            int32_t ext1,
            int32_t ext2,
            int32_t ext3,
            void *user);

}; // class Camera2Device

}; // namespace android

#endif
