import { z } from 'zod';

/**
 * Single local inference provider entry in the shared config file.
 * `kind` distinguishes transport families (llama-swap, deepseek, etc.).
 */
export const LlamaProviderSchema = z.object({
  id: z.string().min(1),
  label: z.string().min(1),
  baseUrl: z.string().url(),
  kind: z.string().min(1).default('llama-swap'),
});

export type LlamaProvider = z.infer<typeof LlamaProviderSchema>;

/**
 * Shape of `/data/llama-providers.json` (or `LLAMA_PROVIDERS_PATH`).
 * When the file is absent, app-local loaders synthesize one legacy
 * provider from `LLAMA_SWAP_URL`.
 */
export const LlamaProvidersFileSchema = z.object({
  defaultProvider: z.string().min(1),
  providers: z.array(LlamaProviderSchema).min(1),
});

export type LlamaProvidersFile = z.infer<typeof LlamaProvidersFileSchema>;

export interface ParsedModelRef {
  providerId: string;
  wireModelId: string;
  isLegacyBareId: boolean;
}

const SEPARATOR = '/';

/**
 * Parse a model reference string.
 *
 * - Composite `"provider/model"` → `{ providerId, wireModelId, isLegacyBareId: false }`
 * - Bare `"model"` (no slash) → resolved against `defaultProvider`,
 *   `{ providerId: defaultProvider, wireModelId: model, isLegacyBareId: true }`
 */
export function parseModelRef(ref: string, defaultProvider: string): ParsedModelRef {
  const slashIdx = ref.indexOf('/');
  if (slashIdx <= 0) {
    // Bare id or empty — resolve to default provider.
    return {
      providerId: defaultProvider,
      wireModelId: ref,
      isLegacyBareId: true,
    };
  }
  return {
    providerId: ref.slice(0, slashIdx),
    wireModelId: ref.slice(slashIdx + 1),
    isLegacyBareId: false,
  };
}

/**
 * Format a provider id + wire model id into the composite `"provider/model"` form.
 */
export function formatModelRef(providerId: string, wireModelId: string): string {
  return `${providerId}${SEPARATOR}${wireModelId}`;
}
