/**
 * start CLI validate — Pure validation, no I/O
 */

import { StartSpecSchema, type StartSpec } from './types.js';

export interface ValidationResult {
  valid: boolean;
  data?: StartSpec;
  blockers: string[];
  warnings: string[];
}

export function validate(spec: unknown): ValidationResult {
  const blockers: string[] = [];
  const warnings: string[] = [];

  let data: StartSpec | undefined;
  try {
    data = StartSpecSchema.parse(spec);
  } catch (err: unknown) {
    const e = err as any;
    if (e.errors) {
      for (const error of e.errors) {
        blockers.push(`${error.path?.join('.')}: ${error.message}`);
      }
    } else {
      blockers.push(`Spec parse failed: ${(err as Error).message}`);
    }
    return { valid: false, blockers, warnings };
  }

  if (!data.name || data.name.trim().length === 0) {
    blockers.push('name cannot be empty');
  }

  const nameTrimmed = data.name.trim();
  if (!/^[a-zA-Z0-9._\-]+$/.test(nameTrimmed)) {
    blockers.push(`name contains invalid characters: ${nameTrimmed}`);
  }

  if (nameTrimmed.length > 100) {
    blockers.push('name too long (max 100 characters)');
  }

  // A release/hotfix name IS the version it will tag — require semver so the
  // tag, the sources and the branch name all agree (Model B). Optional leading
  // `v` and a -prerelease/+build suffix are tolerated.
  if (data.type === 'release' || data.type === 'hotfix') {
    const v = nameTrimmed.replace(/^v/i, '');
    if (!/^\d+\.\d+\.\d+([-.+][0-9A-Za-z.-]+)?$/.test(v)) {
      blockers.push(
        `${data.type} version must be semver (e.g. 5.1.0), got: "${nameTrimmed}". ` +
        `The name becomes the tag and the version written to the sources.`,
      );
    }
  }

  return { valid: blockers.length === 0, data, blockers, warnings };
}
