/*
 * Copyright 2020 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.
 */

#pragma once

#include "CoreLibSetupHelper.h"

#include <android/hardware/automotive/evs/1.1/IEvsCamera.h>
#include <android/hardware/automotive/evs/1.1/IEvsCameraStream.h>
#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
#include <android/hardware/automotive/sv/1.0/types.h>
#include <android/hardware/automotive/sv/1.0/ISurroundViewStream.h>
#include <android/hardware/automotive/sv/1.0/ISurroundView2dSession.h>

#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>

#include <ui/GraphicBuffer.h>

#include <thread>

using namespace ::android::hardware::automotive::evs::V1_1;
using namespace ::android::hardware::automotive::sv::V1_0;
using namespace ::android_auto::surround_view;

using ::android::hardware::Return;
using ::android::hardware::hidl_vec;
using ::android::sp;
using ::std::condition_variable;

using BufferDesc_1_0  = ::android::hardware::automotive::evs::V1_0::BufferDesc;
using BufferDesc_1_1  = ::android::hardware::automotive::evs::V1_1::BufferDesc;

namespace android {
namespace hardware {
namespace automotive {
namespace sv {
namespace V1_0 {
namespace implementation {

class SurroundView2dSession : public ISurroundView2dSession {

    /*
     * FramesHandler:
     * This class can be used to receive camera imagery from an IEvsCamera implementation.  It will
     * hold onto the most recent image buffer, returning older ones.
     * Note that the video frames are delivered on a background thread, while the control interface
     * is actuated from the applications foreground thread.
     */
    class FramesHandler : public IEvsCameraStream {
    public:
        FramesHandler(sp<IEvsCamera> pCamera, sp<SurroundView2dSession> pSession);

    private:
        // Implementation for ::android::hardware::automotive::evs::V1_0::IEvsCameraStream
        Return<void> deliverFrame(const BufferDesc_1_0& buffer) override;

        // Implementation for ::android::hardware::automotive::evs::V1_1::IEvsCameraStream
        Return<void> deliverFrame_1_1(const hidl_vec<BufferDesc_1_1>& buffer) override;
        Return<void> notify(const EvsEventDesc& event) override;

        // Values initialized as startup
        sp <IEvsCamera> mCamera;

        sp<SurroundView2dSession> mSession;
    };

public:
    SurroundView2dSession(sp<IEvsEnumerator> pEvs);
    ~SurroundView2dSession();
    bool initialize();

    // Methods from ::android::hardware::automotive::sv::V1_0::ISurroundViewSession.
    Return<SvResult> startStream(
        const sp<ISurroundViewStream>& stream) override;
    Return<void> stopStream() override;
    Return<void> doneWithFrames(const SvFramesDesc& svFramesDesc) override;

    // Methods from ISurroundView2dSession follow.
    Return<void> get2dMappingInfo(get2dMappingInfo_cb _hidl_cb) override;
    Return<SvResult> set2dConfig(const Sv2dConfig& sv2dConfig) override;
    Return<void> get2dConfig(get2dConfig_cb _hidl_cb) override;
    Return<void> projectCameraPoints(
        const hidl_vec<Point2dInt>& points2dCamera,
        const hidl_string& cameraId,
        projectCameraPoints_cb _hidl_cb) override;

private:
    void processFrames();

    // Set up and open the Evs camera(s), triggered when session is created.
    bool setupEvs();

    // Start Evs camera video stream, triggered when SV stream is started.
    bool startEvs();

    bool handleFrames(int sequenceId);

    bool copyFromBufferToPointers(BufferDesc_1_1 buffer,
                                  SurroundViewInputBufferPointers pointers);

    enum StreamStateValues {
        STOPPED,
        RUNNING,
        STOPPING,
        DEAD,
    };

    // EVS Enumerator to control the start/stop of the Evs Stream
    sp<IEvsEnumerator> mEvs;

    // Instance and metadata for the opened Evs Camera
    sp<IEvsCamera> mCamera;
    CameraDesc mCameraDesc;
    vector<SurroundViewCameraParams> mCameraParams;

    // Stream subscribed for the session.
    sp<ISurroundViewStream> mStream GUARDED_BY(mAccessLock);
    StreamStateValues mStreamState GUARDED_BY(mAccessLock);

    thread mProcessThread; // The thread we'll use to process frames

    // Reference to the inner class, to handle the incoming Evs frames
    sp<FramesHandler> mFramesHandler;

    // Used to signal a set of frames is ready
    condition_variable mFramesSignal GUARDED_BY(mAccessLock);
    bool mProcessingEvsFrames GUARDED_BY(mAccessLock);

    int mSequenceId;

    struct FramesRecord {
        SvFramesDesc frames;
        bool inUse = false;
    };

    FramesRecord mFramesRecord GUARDED_BY(mAccessLock);

    // Synchronization necessary to deconflict mCaptureThread from the main
    // service thread
    mutex mAccessLock;

    vector<string> mEvsCameraIds GUARDED_BY(mAccessLock);

    unique_ptr<SurroundView> mSurroundView GUARDED_BY(mAccessLock);

    vector<SurroundViewInputBufferPointers>
        mInputPointers GUARDED_BY(mAccessLock);
    SurroundViewResultPointer mOutputPointer GUARDED_BY(mAccessLock);

    Sv2dConfig mConfig GUARDED_BY(mAccessLock);
    int mHeight GUARDED_BY(mAccessLock);

    // TODO(b/158479099): Rename it to mMappingInfo
    Sv2dMappingInfo mInfo GUARDED_BY(mAccessLock);
    int mOutputWidth, mOutputHeight GUARDED_BY(mAccessLock);

    sp<GraphicBuffer> mSvTexture GUARDED_BY(mAccessLock);

    bool mIsInitialized GUARDED_BY(mAccessLock) = false;
};

}  // namespace implementation
}  // namespace V1_0
}  // namespace sv
}  // namespace automotive
}  // namespace hardware
}  // namespace android

