// 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 <stdint.h>
#include <stdlib.h>
#include "magma_common_defs.h"
#include "msd.h"

#include "msd_img_buffer.h"
#include "msd_img_connection.h"
#include "msd_img_context.h"
#include "msd_img_device.h"
#include "msd_img_driver.h"
#include "msd_img_semaphore.h"

msd_driver_t*
msd_driver_create(void)
{
	return MsdImgDriver::Create().release();
}

void
msd_driver_configure(msd_driver_t* drv, uint32_t flags)
{
	MsdImgDriver::cast(drv)->configure(flags);
}

void
msd_driver_destroy(msd_driver_t* drv)
{
	MsdImgDriver::Destroy(MsdImgDriver::cast(drv));
}

msd_device_t*
msd_driver_create_device(msd_driver_t* drv, void* device)
{
	if (!device)
	{
		return DRETP(nullptr, "device is null");
	}
	return MsdImgDevice::Create(drv, device).release();
}

void
msd_device_destroy(msd_device_t* dev)
{
	MsdImgDevice::Destroy(MsdImgDevice::cast(dev));
}

magma_status_t
msd_device_query(msd_device_t* device, uint64_t id, uint64_t* value_out)
{
	return MAGMA_STATUS_OK;
}

void
msd_device_dump_status(msd_device_t* dev, uint32_t dump_flags)
{
	MsdImgDevice::cast(dev)->DumpStatus(dump_flags);
}

msd_connection_t*
msd_device_open(msd_device_t* dev, msd_client_id_t client_id)
{
	MsdImgDevice* device = MsdImgDevice::cast(dev);
	auto connection = std::make_unique<MsdImgConnection>(device, client_id);
	if (!connection->Init())
	{
		return DRETP(nullptr, "Failed to initialize connection");
	}

	return connection.release();
}

void
msd_connection_close(msd_connection_t* connection)
{
	delete MsdImgConnection::Cast(connection);
}

magma_status_t
msd_connection_map_buffer_gpu(msd_connection_t* connection,
			      msd_buffer_t* buffer,
			      uint64_t gpu_va,
			      uint64_t page_offset,
			      uint64_t page_count,
			      uint64_t flags)
{
	return MAGMA_STATUS_OK;
}
magma_status_t
msd_connection_unmap_buffer_gpu(msd_connection_t* connection, msd_buffer_t* buffer, uint64_t gpu_va)
{
	return MAGMA_STATUS_OK;
}
magma_status_t
msd_connection_commit_buffer(msd_connection_t* connection, msd_buffer_t* buffer, uint64_t page_offset, uint64_t page_count)
{
	return MAGMA_STATUS_OK;
}

void
msd_connection_set_notification_callback(msd_connection_t* connection,
					 msd_connection_notification_callback_t callback,
					 void* token)
{
}

msd_context_t*
msd_connection_create_context(msd_connection_t* connection)
{
	return new MsdImgContext(MsdImgConnection::Cast(connection));
}

void
msd_context_destroy(msd_context_t* ctx)
{
	delete MsdImgContext::cast(ctx);
}

magma_status_t
msd_context_execute_command_buffer(msd_context_t* ctx,
				   msd_buffer_t* cmd_buf,
				   msd_buffer_t** exec_resources,
				   msd_semaphore_t** wait_semaphores,
				   msd_semaphore_t** signal_semaphores)
{
	MsdImgConnection* connection = MsdImgContext::cast(ctx)->connection();

	return connection->ExecuteCommandBuffer(cmd_buf, exec_resources, signal_semaphores);
}

magma_status_t
msd_context_execute_immediate_commands(msd_context_t* ctx,
				       uint64_t commands_size,
				       void* commands,
				       uint64_t semaphore_count,
				       msd_semaphore_t** semaphores)
{
	return MAGMA_STATUS_OK;
}

void
msd_context_release_buffer(msd_context_t* context, msd_buffer_t* buffer)
{
}

void
msd_connection_release_buffer(msd_connection_t* connection, msd_buffer_t* buffer)
{
}

magma_status_t
msd_device_query_returns_buffer(struct msd_device_t* device, uint64_t id, uint32_t* buffer_out)
{
	return MAGMA_STATUS_UNIMPLEMENTED;
}
