/*
 * Helper to calculate optimal SWRAP_MAX_PASSED_FDS and
 * SWRAP_MAX_PASSED_SOCKET_INFO so that struct swrap_unix_scm_rights fits within
 * PIPE_BUF
 */

#include <stdio.h>
#include <limits.h>
#include <stddef.h>

#include "../src/socket_wrapper.c"

int main(void)
{
	size_t si_size = sizeof(struct socket_info);
	size_t scm_rights_size = sizeof(struct swrap_unix_scm_rights);
	size_t header_size;
	size_t payload_base_size;
	size_t available_space;
	size_t max_fds;
	size_t max_socket_infos;
	size_t calculated_total_size;

	printf("Current configuration:\n");
	printf("  SWRAP_MAX_PASSED_FDS = %zu\n", SWRAP_MAX_PASSED_FDS);
	printf("  SWRAP_MAX_PASSED_SOCKET_INFO = %zu\n",
	       SWRAP_MAX_PASSED_SOCKET_INFO);
	printf("  sizeof(struct socket_info) = %zu bytes\n", si_size);
	printf("  sizeof(struct swrap_unix_scm_rights) = %zu bytes\n",
	       scm_rights_size);
	printf("\n");

	/* Calculate header size and payload base size using offsetof */
	header_size = offsetof(struct swrap_unix_scm_rights, payload);
	payload_base_size = offsetof(struct swrap_unix_scm_rights_payload, idxs);

	available_space = PIPE_BUF - header_size - payload_base_size;

	printf("PIPE_BUF = %d bytes\n", PIPE_BUF);
	printf("Header size (offsetof payload) = %zu bytes\n", header_size);
	printf("Payload base size (offsetof idxs) = %zu bytes\n",
	       payload_base_size);
	printf("Available space for arrays = %zu bytes\n", available_space);
	printf("\n");

	/* Calculate maximum FDs and socket_infos that fit */
	/* Formula: available_space = (max_fds * sizeof(int8_t)) +
	 * (max_socket_infos * sizeof(socket_info)) */
	/* Assuming max_fds == max_socket_infos: available_space = max * (1 +
	 * sizeof(socket_info)) */
	max_fds = available_space / (sizeof(int8_t) + si_size);
	max_socket_infos = max_fds;

	printf("Calculated maximum values:\n");
	printf("  SWRAP_MAX_PASSED_FDS = %zu\n", max_fds);
	printf("  SWRAP_MAX_PASSED_SOCKET_INFO = %zu\n", max_socket_infos);
	printf("\n");

	/* Verify the calculation */
	calculated_total_size = header_size + payload_base_size +
				(max_fds * sizeof(int8_t)) +
				(max_socket_infos * si_size);
	printf("Verification:\n");
	printf("  Calculated total size (struct swrap_unix_scm_rights) = %zu "
	       "bytes\n",
	       calculated_total_size);
	printf("  Space used = %.1f%% of PIPE_BUF\n",
	       (calculated_total_size * 100.0) / PIPE_BUF);
	printf("  Space remaining = %zu bytes\n",
	       PIPE_BUF - calculated_total_size);
	printf("  Fits in PIPE_BUF: %s\n",
	       calculated_total_size <= PIPE_BUF ? "YES" : "NO");

	return 0;
}
