#include <dri/pci/pci.h>
#include <dri/pci/vendors.h>
#include <io.h>
#include <log.h>
#include <alloc.h>

static uint num_drivers, size_drivers;
static struct pci_device_driver *drivers;

uint pci_config_readd(uchar bus, uchar slot, uchar func, uchar offset)
{
	uint address =
		(bus << 16) | (slot << 11) | (func << 8) | (offset << 2) | 0x80000000;

	outl(PCI_CONFIG_ADDRESS, address);

	return inl(PCI_CONFIG_DATA);
}

struct pci_device pci_check_device(uchar bus, uchar slot, uchar func)
{

	uint vendor_device = pci_config_readd(bus, slot, func, 0);
	ushort vendor = vendor_device & 0xffff;

	struct pci_device device;
	device.valid = false;

	if (vendor != 0xffff)
	{
		device.valid = true;

		device.device_id = vendor_device >> 16;
		device.vendor = pci_vendor_by_id(vendor);

		// 3rd dword
		uint class_subclass = pci_config_readd(bus, slot, func, 2);
		device.class = class_subclass >> 24;
		device.subclass = (class_subclass >> 16) & 0xff;
		device.prog_if = (class_subclass >> 8) & 0xff;
	}

	return device;
}

struct pci_vendor *pci_vendor_by_id(ushort id)
{
	// Find vendor using binary search

	uint start = 0, max = pci_num_vendors;

	while (true)
	{
		if (max == start)
			// Can't find one
			return NULL;

		uint guess = (max - start) / 2 + start;

		if (pci_vendors[guess].id == id)
			return &pci_vendors[guess];
		else if (pci_vendors[guess].id > id)
			max = guess;
		else
			start = guess;
	}
}

void pci_print_devices()
{
	kprintf(INFO "Enumerating PCI devices:\n");
	for (int bus = 0; bus < 0xff; bus++)
	{
		for (int slot = 0; slot < 32; slot++)
		{
			for (int func = 0; func < 8; func++)
			{
				struct pci_device dev = pci_check_device(bus, slot, func);

				if (dev.valid)
				{
					kprintf(INFO "%d %d %d --- d:0x%x --- %d:%d:%d --- %s\n", bus,
							slot, func, dev.device_id, dev.class, dev.subclass,
							dev.prog_if, dev.vendor->name);
				}
			}
		}
	}
}

void pci_register_device_driver(struct pci_device_driver driver)
{
	if (num_drivers == size_drivers)
	{
		size_drivers += 8;
		drivers = realloc(drivers, sizeof(struct pci_device_driver) * size_drivers);
	}

	driver.loaded = 0;
	drivers[num_drivers++] = driver;
}

void pci_init()
{
	num_drivers = 0;
	size_drivers = 4;
	drivers = malloc(sizeof(struct pci_device_driver) * size_drivers);
}

void pci_load()
{
	for (int bus = 0; bus < 0xff; bus++)
	{
		for (int slot = 0; slot < 32; slot++)
		{
			for (int func = 0; func < 8; func++)
			{
				struct pci_device dev = pci_check_device(bus, slot, func);

				// Do any drivers support this?

				for (int i = 0; i < num_drivers; i++)
				{
					if (drivers[i].supports(&dev))
					{
						drivers[i].loaded++;
						drivers[i].dev = dev;
						drivers[i].init(dev, bus, slot, func);
					}
				}
			}
		}
	}
}

void pci_print_drivers()
{
	kprintf(INFO "Enumerating PCI device drivers:\n");
	for (int i = 0; i < num_drivers; i++)
	{
		for (int j = 0; j < drivers[i].loaded; j++)
		{
			struct pci_device_driver d = drivers[i];
			kprintf(INFO "Driver: %s, vendor: %s\n", d.generic_name, d.dev.vendor->name);
		}
	}
}
