scenario.h

/*
 * Proxy Pool Governor — scenario (.pps) file format interface.
 *
 * Copyright (C) 2026  SWGY, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

#ifndef SCENARIO_H
#define SCENARIO_H

#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>

#define SCENARIO_MAX_POOLS    256
#define SCENARIO_MAX_SERVICES 256
#define SCENARIO_MAX_NAME     64
#define SCENARIO_VERSION      1

/*
 * Single aggregated stats record
 */
typedef struct {
	double   timestamp;
	uint8_t  pool;
	uint8_t  service;
	double   rate_success;
	double   rate_lost_race;
	double   rate_302;
	double   rate_timeout;
	double   rate_ssl;
	double   rate_other;
	double   response_time;
	double   avg_success;
	double   avg_response_time;
	double   stddev_success;
	double   stddev_response_time;
} ScenarioRecord;

/*
 * Scenario file handle
 */
typedef struct {
	FILE    *fp;
	int      mode;  /* 'r' or 'w' */

	/* Metadata */
	size_t   num_pools;
	size_t   num_services;
	size_t   num_records;  /* 0 if unknown/streaming */
	char     pool_names[SCENARIO_MAX_POOLS][SCENARIO_MAX_NAME];
	char     service_names[SCENARIO_MAX_SERVICES][SCENARIO_MAX_NAME];

	/* Read state */
	size_t   records_read;
	int      header_parsed;
	int      in_data_section;
} Scenario;

/*
 * Open scenario file for reading
 * Returns NULL on error, sets errno
 */
Scenario *scenario_open_read(const char *path);

/*
 * Open scenario file for writing
 * Caller must populate pool_names, service_names, num_pools, num_services
 * before calling scenario_write_header()
 */
Scenario *scenario_open_write(const char *path);

/*
 * Write header (call after populating metadata, before writing records)
 * num_records can be 0 if unknown
 */
int scenario_write_header(Scenario *s, size_t num_records);

/*
 * Read next record
 * Returns 1 on success, 0 on EOF, -1 on error
 */
int scenario_read(Scenario *s, ScenarioRecord *rec);

/*
 * Write a record
 * Returns 0 on success, -1 on error
 */
int scenario_write(Scenario *s, const ScenarioRecord *rec);

/*
 * Close and free scenario handle
 */
void scenario_close(Scenario *s);

/*
 * Lookup helpers
 */
const char *scenario_pool_name(const Scenario *s, uint8_t id);
const char *scenario_service_name(const Scenario *s, uint8_t id);
int scenario_pool_id(const Scenario *s, const char *name);
int scenario_service_id(const Scenario *s, const char *name);

#endif /* SCENARIO_H */