// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "arm-isp-test.h"
#include "global_regs.h"
#include "pingpong_regs.h"
#include "stats-mgr.h"

#include <atomic>
#include <ddk/metadata/camera.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/platform-device-lib.h>
#include <ddk/protocol/platform/bus.h>
#include <ddk/protocol/platform/device.h>
#include <ddktl/device.h>
#include <ddktl/pdev.h>
#include <ddktl/protocol/composite.h>
#include <ddktl/protocol/empty-protocol.h>
#include <fbl/unique_ptr.h>
#include <fuchsia/hardware/camera/c/fidl.h>
#include <hw/reg.h>
#include <lib/fidl-utils/bind.h>
#include <lib/zx/interrupt.h>
#include <threads.h>
#include <zircon/fidl.h>

namespace camera {
// |ArmIspDevice| is spawned by the driver in |arm-isp.cpp|
// This provides the interface provided in camera.fidl in Zircon.
class ArmIspDevice;
using IspDeviceType = ddk::Device<ArmIspDevice, ddk::Unbindable, ddk::Messageable>;

class ArmIspDevice : public IspDeviceType,
                     public ddk::EmptyProtocol<ZX_PROTOCOL_CAMERA> {
public:
    DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(ArmIspDevice);

    explicit ArmIspDevice(zx_device_t* parent,
                          ddk ::MmioBuffer hiu_mmio,
                          ddk ::MmioBuffer power_mmio,
                          ddk ::MmioBuffer memory_pd_mmio,
                          ddk ::MmioBuffer reset_mmio,
                          ddk ::MmioBuffer isp_mmio,
                          mmio_buffer_t local_mmio,
                          zx::interrupt isp_irq,
                          zx::bti bti,
                          zx_device_t* camera_sensor)
        : IspDeviceType(parent), pdev_(parent),
          hiu_mmio_(std::move(hiu_mmio)), power_mmio_(std::move(power_mmio)),
          memory_pd_mmio_(std::move(memory_pd_mmio)), reset_mmio_(std::move(reset_mmio)),
          isp_mmio_(std::move(isp_mmio)), isp_mmio_local_(local_mmio, 0),
          isp_irq_(std::move(isp_irq)), bti_(std::move(bti)),
          camera_sensor_(camera_sensor) {}

    ~ArmIspDevice();

    static zx_status_t Create(void* ctx, zx_device_t* parent);

    // Methods required by the ddk.
    void DdkRelease();
    void DdkUnbind();
    zx_status_t DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn);

    // ISP Init Sequences (init_sequences.cpp)
    void IspLoadSeq_linear();
    void IspLoadSeq_settings();
    void IspLoadSeq_fs_lin_2exp();
    void IspLoadSeq_fs_lin_3exp();
    void IspLoadSeq_fs_lin_4exp();
    void IspLoadSeq_settings_context();
    void IspLoadCustomSequence();

private:
    zx_status_t InitIsp();
    zx_status_t IspContextInit();

    // A skeleton function for testing the ISP with the ISPDeviceTester:
    zx_status_t RunTests() { return ZX_OK; }

    void ShutDown();
    void PowerUpIsp();
    void IspHWReset(bool reset);
    int IspIrqHandler();
    void CopyContextInfo(uint8_t config_space,
                         uint8_t direction);
    void CopyMeteringInfo(uint8_t config_space);
    zx_status_t SetPort(uint8_t kMode);
    bool IsFrameProcessingInProgress();

    // DDKMessage Helper Functions.
    zx_status_t StartStreaming();
    zx_status_t StopStreaming();
    zx_status_t ReleaseFrame(uint32_t buffer_id);
    zx_status_t GetFormats(uint32_t index, fidl_txn_t* txn);
    zx_status_t CreateStream(const fuchsia_sysmem_BufferCollectionInfo* buffer_collection,
                             const fuchsia_hardware_camera_FrameRate* rate,
                             zx_handle_t stream,
                             zx_handle_t stream_token);
    zx_status_t GetDeviceInfo(fidl_txn_t* txn);

    static constexpr fuchsia_hardware_camera_Stream_ops_t stream_ops = {
        .Start = fidl::Binder<ArmIspDevice>::BindMember<&ArmIspDevice::StartStreaming>,
        .Stop = fidl::Binder<ArmIspDevice>::BindMember<&ArmIspDevice::StopStreaming>,
        .ReleaseFrame = fidl::Binder<ArmIspDevice>::BindMember<&ArmIspDevice::ReleaseFrame>,
    };

    static constexpr fuchsia_hardware_camera_Control_ops_t control_ops = {
        .GetFormats = fidl::Binder<ArmIspDevice>::BindMember<&ArmIspDevice::GetFormats>,
        .CreateStream = fidl::Binder<ArmIspDevice>::BindMember<&ArmIspDevice::CreateStream>,
        .GetDeviceInfo = fidl::Binder<ArmIspDevice>::BindMember<&ArmIspDevice::GetDeviceInfo>,
    };

    ddk::PDev pdev_;

    ddk::MmioBuffer hiu_mmio_;
    ddk::MmioBuffer power_mmio_;
    ddk::MmioBuffer memory_pd_mmio_;
    ddk::MmioBuffer reset_mmio_;
    ddk::MmioBuffer isp_mmio_;
    // MmioView is currently used and created using a custom mmio_buffer_t
    // populated with malloced memory.
    // We can switch to using the actual mmio_buffer_t
    // when we plan to use SW-HW context, in order to make a easy switch.
    ddk::MmioView isp_mmio_local_;

    zx::interrupt isp_irq_;
    thrd_t irq_thread_;
    zx::bti bti_;
    std::atomic<bool> running_;

    ddk::CameraSensorProtocolClient camera_sensor_;

    fbl::unique_ptr<camera::StatsManager> statsMgr_;

    sync_completion_t frame_processing_signal_;

    friend class ArmIspDeviceTester;
};

} // namespace camera
