/**
 * parse-csproj-version.ts — Extract <Version> from a .csproj file.
 *
 * The {context}_v{version}_{seq}_{Description} naming convention requires a
 * version tag. We prefer the csproj <Version> element; when absent we fall
 * back to <AssemblyVersion> or default to "0.1.0".
 *
 * Pre-release suffixes and build metadata are stripped so "0.1.0-dev.3" and
 * "0.1.0+sha.abc" both normalize to "0.1.0".
 */
import { readText } from '../../../lib/fs.js';

const DEFAULT_VERSION = '0.1.0';

export async function parseCsprojVersion(csprojPath: string): Promise<string> {
  let content: string;
  try {
    content = await readText(csprojPath);
  } catch {
    return DEFAULT_VERSION;
  }

  const version = matchTag(content, 'Version')
    ?? matchTag(content, 'AssemblyVersion')
    ?? matchTag(content, 'FileVersion');

  if (!version) return DEFAULT_VERSION;

  // Strip pre-release and build metadata: 0.1.0-dev.1+sha → 0.1.0
  const core = version.split(/[-+]/)[0].trim();
  return /^\d+(\.\d+){0,3}$/.test(core) ? core : DEFAULT_VERSION;
}

function matchTag(content: string, tag: string): string | null {
  const re = new RegExp(`<${tag}>([^<]+)</${tag}>`, 'i');
  const m = content.match(re);
  return m ? m[1].trim() : null;
}

export function normalizeVersionForName(version: string): string {
  // Defensive: strip pre-release / build metadata even if the caller forgot
  // to run it through parseCsprojVersion first.
  const core = version.split(/[-+]/)[0].trim() || version;
  return core.replace(/\./g, '_');
}
