// AGPL-3.0-only
//
// This is free software for the public good of a permacomputer
// hosted at permacomputer.com, an always-on computer by the people, for the
// people. One which is durable, easy to repair, and distributed like tap water
// for machine learning intelligence.
//
// The permacomputer is community-owned infrastructure optimized around
// four values:
//
//   TRUTH    - First principles, math & science, open source code
//   FREEDOM  - Voluntary partnerships, freedom from tyranny & corporate control
//   HARMONY  - Minimal waste, self-renewing systems with diverse connections
//   LOVE     - Be yourself without hurting others, cooperation through natural law
//
// This software contributes to that vision by making machine learning
// accessible to everyone through a free, open, embeddable chat interface.
// Code is seeds to sprout on any abandoned technology.
//
// Learn more: https://www.permacomputer.com
//
// NO WARRANTY. THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
//
// Copyright 2025-2026 TimeHexOn & foxhop & russell@unturf
// https://www.permacomputer.com

// Groq-aware fetch wrapper that handles TPM rate limits
// Use this for all API requests to Groq endpoints

export async function groqAwareFetch(url, options = {}) {
	// If not a Groq URL, use regular fetch
	if (!url.includes('groq.com')) {
		return fetch(url, options);
	}

	// Groq-specific retry logic for TPM rate limits
	let retryCount = 0;
	const maxRetries = 3;
	
	while (retryCount < maxRetries) {
		try {
			const response = await fetch(url, options);
			
			// Check for Groq rate limit error
			if (response.status === 429 || response.status === 400) {
				const responseClone = response.clone(); // Clone so we can read body twice
				const errorText = await responseClone.text();
				
				if (errorText.includes('rate_limit_exceeded') && errorText.includes('TPM')) {
					console.log(`Groq TPM rate limit hit, waiting 60 seconds before retry ${retryCount + 1}/${maxRetries}...`);
					
					// Wait 60 seconds for TPM window to reset
					await new Promise(resolve => setTimeout(resolve, 60000));
					retryCount++;
					continue;
				}
			}
			
			// Return response (success or non-rate-limit error)
			return response;
			
		} catch (error) {
			// Network errors etc - don't retry these
			throw error;
		}
	}
	
	// If we get here, we've exhausted retries
	throw new Error("Groq TPM rate limit exceeded after multiple retries. Please try again later.");
}

// Generator version for streaming responses
export async function* groqAwareStreamingFetch(url, options = {}) {
	// If not a Groq URL, use regular fetch and pass through
	if (!url.includes('groq.com')) {
		const response = await fetch(url, options);
		const reader = response.body.getReader();
		const decoder = new TextDecoder();
		
		while (true) {
			const { done, value } = await reader.read();
			if (done) break;
			yield decoder.decode(value, { stream: true });
		}
		return;
	}

	// Groq-specific retry logic for TPM rate limits
	let retryCount = 0;
	const maxRetries = 3;
	
	while (retryCount < maxRetries) {
		try {
			const response = await fetch(url, options);
			
			// Check for Groq rate limit error
			if (response.status === 429 || response.status === 400) {
				const responseClone = response.clone();
				const errorText = await responseClone.text();
				
				if (errorText.includes('rate_limit_exceeded') && errorText.includes('TPM')) {
					console.log(`Groq TPM rate limit hit, waiting 60 seconds before retry ${retryCount + 1}/${maxRetries}...`);
					yield "⏳ Groq rate limit reached, waiting 60 seconds for TPM window to reset...";
					
					await new Promise(resolve => setTimeout(resolve, 60000));
					retryCount++;
					continue;
				}
			}
			
			// Success or non-rate-limit error - process streaming response
			if (!response.ok) {
				const errorText = await response.text();
				throw new Error(`HTTP error! status: ${response.status}: ${errorText}`);
			}
			
			const reader = response.body.getReader();
			const decoder = new TextDecoder();
			
			while (true) {
				const { done, value } = await reader.read();
				if (done) break;
				yield decoder.decode(value, { stream: true });
			}
			return;
			
		} catch (error) {
			// Network errors etc - don't retry these
			throw error;
		}
	}
	
	throw new Error("Groq TPM rate limit exceeded after multiple retries. Please try again later.");
}