// 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 "virtual_camera_device.h"

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/platform-defs.h>
#include <fbl/alloc_checker.h>
#include <fbl/unique_ptr.h>

namespace virtual_camera {

zx_status_t VirtualCameraDevice::Create(void* ctx, zx_device_t* parent) {
    fbl::AllocChecker ac;
    auto device = fbl::make_unique_checked<VirtualCameraDevice>(&ac, parent);
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }

    zx_status_t status = device->DdkAdd("virtual_camera");
    if (status != ZX_OK) {
        zxlogf(
            ERROR,
            "virtual_camera_device: Could not create virtual camera device: %d\n",
            status);
        return status;
    }

    // device intentionally leaked as it is now held by DevMgr.
    __UNUSED auto* dev = device.release();
    return ZX_OK;
}

void VirtualCameraDevice::DdkUnbind() {
    DdkRemove();
}

void VirtualCameraDevice::DdkRelease() {
    delete this;
}

zx_status_t VirtualCameraDevice::DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn) {
    zx_status_t status = fuchsia_hardware_camera_Stream_try_dispatch(
        this, txn, msg, &stream_ops);

    if (status == ZX_ERR_NOT_SUPPORTED) {
        status = fuchsia_hardware_camera_Control_try_dispatch(this, txn, msg,
                                                              &control_ops);
    }
    return status;
}

zx_status_t VirtualCameraDevice::StartStreaming() {
    zxlogf(INFO, "virtual_camera_device: StartStreaming is not yet supported\n");
    // Return ok since the function doesn't send a message back to the client.
    return ZX_OK;
}

zx_status_t VirtualCameraDevice::StopStreaming() {
    zxlogf(INFO, "virtual_camera_device: StopStreaming is not yet supported\n");
    // Return ok since the function doesn't send a message back to the client.
    return ZX_OK;
}

zx_status_t VirtualCameraDevice::ReleaseFrame(uint32_t buffer_id) {
    return buffers_.BufferRelease(buffer_id);
}

zx_status_t VirtualCameraDevice::GetFormats(uint32_t index, fidl_txn_t* txn) {
    fuchsia_hardware_camera_VideoFormat formats[16];

    fuchsia_hardware_camera_VideoFormat format = {
        .format = {.width = 640,
                   .height = 480,
                   .layers = 1,
                   .pixel_format =
                       {
                           .type = fuchsia_sysmem_PixelFormatType_BGRA32,
                           .has_format_modifier = false,
                           .format_modifier = {.value = 0},
                       },
                   .color_space = {.type = fuchsia_sysmem_ColorSpaceType_SRGB},
                   .planes = {{.byte_offset = 0, .bytes_per_row = 4 * 640},
                              {.byte_offset = 0, .bytes_per_row = 4 * 640},
                              {.byte_offset = 0, .bytes_per_row = 4 * 640},
                              {.byte_offset = 0, .bytes_per_row = 4 * 640}}},
        .rate =
            {
                .frames_per_sec_numerator = 30,
                .frames_per_sec_denominator = 1,
            },
    };

    formats[0] = format;
    return fuchsia_hardware_camera_ControlGetFormats_reply(txn, formats, 1, 1,
                                                           ZX_OK);
}

zx_status_t VirtualCameraDevice::CreateStream(
    const fuchsia_sysmem_BufferCollectionInfo* buffer_collection_info,
    const fuchsia_hardware_camera_FrameRate* rate, zx_handle_t stream,
    zx_handle_t stream_token) {
    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t VirtualCameraDevice::GetDeviceInfo(fidl_txn_t* txn) {
    fuchsia_hardware_camera_DeviceInfo info;
    info.output_capabilities = fuchsia_hardware_camera_CAMERA_OUTPUT_STREAM;
    info.max_stream_count = 1;
    return fuchsia_hardware_camera_ControlGetDeviceInfo_reply(txn, &info);
}

static zx_driver_ops_t driver_ops = []() {
    zx_driver_ops_t ops;
    ops.version = DRIVER_OPS_VERSION;
    ops.bind = VirtualCameraDevice::Create;
    return ops;
}();

} // namespace virtual_camera

// clang-format off
ZIRCON_DRIVER_BEGIN(virtual_camera, virtual_camera::driver_ops, "vcamera", "0.1", 3)
  BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_TEST),
  BI_ABORT_IF(NE, BIND_PLATFORM_DEV_PID, PDEV_PID_VCAMERA_TEST),
  BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_TEST_VCAMERA),
ZIRCON_DRIVER_END(virtual_camera)
// clang-format on
