#!/usr/bin/env bash
#
# _lib.sh — Shared functions for mosaic prdy tools
#
# Usage: source ~/.config/mosaic/tools/prdy/_lib.sh
#
# Provides PRD detection, section validation, and system prompt generation
# for interactive PRD creation/update sessions.

MOSAIC_HOME="${MOSAIC_HOME:-$HOME/.config/mosaic}"
PRD_CANONICAL="docs/PRD.md"
PRD_JSON_ALT="docs/PRD.json"

# ─── Color support ───────────────────────────────────────────────────────────

if [[ -t 1 ]]; then
  C_GREEN='\033[0;32m'
  C_RED='\033[0;31m'
  C_YELLOW='\033[0;33m'
  C_CYAN='\033[0;36m'
  C_BOLD='\033[1m'
  C_DIM='\033[2m'
  C_RESET='\033[0m'
else
  C_GREEN='' C_RED='' C_YELLOW='' C_CYAN='' C_BOLD='' C_DIM='' C_RESET=''
fi

ok()   { echo -e "  ${C_GREEN}✓${C_RESET} $1"; }
warn() { echo -e "  ${C_YELLOW}⚠${C_RESET} $1" >&2; }
fail() { echo -e "  ${C_RED}✗${C_RESET} $1" >&2; }
info() { echo -e "  ${C_CYAN}ℹ${C_RESET} $1"; }
step() { echo -e "\n${C_BOLD}$1${C_RESET}"; }

# ─── Dependency checks ──────────────────────────────────────────────────────

_require_cmd() {
  local cmd="$1"
  if ! command -v "$cmd" &>/dev/null; then
    fail "'$cmd' is required but not installed"
    return 1
  fi
}

prdy_runtime() {
  local runtime="${MOSAIC_PRDY_RUNTIME:-claude}"
  case "$runtime" in
    claude|codex) echo "$runtime" ;;
    *) echo "claude" ;;
  esac
}

prdy_runtime_command() {
  local runtime
  runtime="$(prdy_runtime)"
  echo "$runtime"
}

# ─── PRD detection ───────────────────────────────────────────────────────────

# Find the PRD file in a project directory.
# Returns the path (relative to project root) or empty string.
find_prd() {
  local project="${1:-.}"
  if [[ -f "$project/$PRD_CANONICAL" ]]; then
    echo "$project/$PRD_CANONICAL"
  elif [[ -f "$project/$PRD_JSON_ALT" ]]; then
    echo "$project/$PRD_JSON_ALT"
  fi
}

# ─── Section validation manifest ─────────────────────────────────────────────

# 10 required sections per ~/.config/mosaic/guides/PRD.md
# Each entry: "label|grep_pattern" (extended regex, case-insensitive via grep -iE)
PRDY_REQUIRED_SECTIONS=(
  "Problem Statement|^#{2,3} .*(problem statement|objective)"
  "Scope / Non-Goals|^#{2,3} .*(scope|non.goal|out of scope|in.scope)"
  "User Stories / Requirements|^#{2,3} .*(user stor|stakeholder|user.*requirement)"
  "Functional Requirements|^#{2,3} .*functional requirement"
  "Non-Functional Requirements|^#{2,3} .*non.functional"
  "Acceptance Criteria|^#{2,3} .*acceptance criteria|\*\*acceptance criteria\*\*|- \[ \]"
  "Technical Considerations|^#{2,3} .*(technical consideration|constraint|dependenc)"
  "Risks / Open Questions|^#{2,3} .*(risk|open question)"
  "Success Metrics / Testing|^#{2,3} .*(success metric|test|verification)"
  "Milestones / Delivery|^#{2,3} .*(milestone|delivery|scope version)"
)

# ─── System prompt builder ───────────────────────────────────────────────────

# Build the specialized system prompt for PRD sessions.
# Usage: build_prdy_system_prompt <mode>
#   mode: "init" or "update"
build_prdy_system_prompt() {
  local mode="${1:-init}"
  local guide_file="$MOSAIC_HOME/guides/PRD.md"
  local template_file="$MOSAIC_HOME/templates/docs/PRD.md.template"

  cat <<'PROMPT_HEADER'
# Mosaic PRD Agent — Behavioral Contract

You are a specialized PRD (Product Requirements Document) agent. Your sole purpose is to help the user create or update a comprehensive PRD document.

## Mode Declaration (Hard Gate)

PROMPT_HEADER

  if [[ "$mode" == "init" ]]; then
    cat <<'INIT_MODE'
Your first response MUST start with: "Now initiating PRD Creation mode..."

You are creating a NEW PRD. The output file is `docs/PRD.md`.

## Workflow

1. Read the project directory to understand context (README, package.json, existing docs, source structure)
2. Ask the user 3-5 clarifying questions with lettered options (A/B/C/D) so they can answer "1A, 2C, 3B"
3. Focus questions on: problem/goal, target users, scope boundaries, milestone structure, success criteria
4. After answers (or if the description is sufficiently complete), generate the full PRD
5. Write to `docs/PRD.md` (create `docs/` directory if it doesn't exist)
6. Run `mosaic prdy validate` (or `~/.config/mosaic/tools/prdy/prdy-validate.sh`) and show the output
7. If validation fails, fix the missing sections or metadata immediately and re-run validation until it passes
8. Only after validation passes, tell the user: "PRD written to docs/PRD.md — validation passed."

INIT_MODE
  else
    cat <<'UPDATE_MODE'
Your first response MUST start with: "Now initiating PRD Update mode..."

You are UPDATING an existing PRD. Read `docs/PRD.md` (or `docs/PRD.json`) first.

## Workflow

1. Read the existing PRD file completely
2. Summarize the current state to the user (title, status, milestone count, open questions)
3. Ask the user what changes or additions are needed
4. Make targeted modifications — do NOT rewrite sections that don't need changes
5. Preserve existing user stories, FRs, and acceptance criteria unless explicitly asked to change them
6. Run `mosaic prdy validate` (or `~/.config/mosaic/tools/prdy/prdy-validate.sh`) and show the output
7. If validation fails, fix the missing sections or metadata immediately and re-run validation until it passes
8. Only after validation passes, tell the user: "PRD updated — validation passed."

UPDATE_MODE
  fi

  cat <<'CONSTRAINTS'
## Hard Constraints

MUST:
- Save output to `docs/PRD.md` only
- Include ALL 10 required sections from the Mosaic PRD guide (included below)
- Number functional requirements as FR-1, FR-2, ... in sequence
- Group user stories under named Milestones (e.g., "Milestone 0.0.4 — Foundation")
- Format user stories as US-NNN with Description and Acceptance Criteria checkboxes
- Mark all guessed decisions with `ASSUMPTION:` and rationale
- Include a Metadata block (Owner, Date, Status, Mission ID, Scope Version)
- Write for junior developers and AI agents — explicit, unambiguous, no jargon
- Include "Typecheck and lint pass" in acceptance criteria for code stories
- Include "Verify in browser using dev-browser skill" for UI stories

MUST NOT:
- Write any implementation code
- Modify any files other than `docs/PRD.md`
- Skip clarifying questions when the feature description is ambiguous
- Begin implementation of any requirements
- Invent requirements silently — all guesses must be marked with ASSUMPTION

CONSTRAINTS

  cat <<'STRUCTURE'
## Required PRD Structure (Gold Standard)

Follow this exact structure. Every section is required.

```
# PRD: {Feature/Project Name}

## Metadata
- **Owner:** {name}
- **Date:** {yyyy-mm-dd}
- **Status:** draft|planning|approved|in-progress|completed
- **Mission ID:** {kebab-case-id-yyyymmdd}
- **Scope Version:** {e.g., 0.0.4 → 0.0.5 → 0.1.0}

## Introduction
Narrative overview: what this is, the context it lives in, what exists before this work.

## Problem Statement
Numbered list of specific pain points being solved.

## Goals
Bullet list of measurable objectives.

## Milestones
Named milestones (e.g., "Milestone 0.0.4 — Design System Foundation").
Each milestone has a one-paragraph description of its theme.

## User Stories (grouped under milestones)

### Milestone X.Y.Z — {Theme Name}

#### US-001: {Title}
**Description:** As a {user}, I want {feature} so that {benefit}.

**Acceptance Criteria:**
- [ ] Specific verifiable criterion
- [ ] Another criterion
- [ ] Typecheck and lint pass
- [ ] [UI stories only] Verify in browser using dev-browser skill

---

## Functional Requirements
Numbered FR-1 through FR-N. Group by subsystem if applicable.
Each: "FR-N: {subject} must {behavior}"

## Non-Goals (Out of Scope)
Numbered list of explicit exclusions with brief rationale.

## Design Considerations
- Design references (mockups, existing design systems)
- Key visual/UX elements
- Component hierarchy

## Technical Considerations

### Dependencies
Libraries, packages, external services required.

### Build & CI
Build pipeline, CI gates, quality checks.

### Deployment
Target infrastructure, deployment method, image tagging strategy.

### Risks
Technical risks that could affect delivery.

## Success Metrics
Numbered list of measurable success conditions.

## Open Questions
Numbered list. For unresolved items, add:
(ASSUMPTION: {best-guess decision} — {rationale})
```

STRUCTURE

  cat <<'QUESTIONS'
## Clarifying Question Format

When asking clarifying questions, use numbered questions with lettered options:

```
1. What is the primary goal?
   A. Option one
   B. Option two
   C. Option three
   D. Other: [please specify]

2. What is the target scope?
   A. Minimal viable
   B. Full-featured
   C. Backend only
   D. Frontend only
```

Tell the user they can answer with shorthand like "1A, 2C, 3B" for quick iteration.

QUESTIONS

  # Include the live PRD guide
  if [[ -f "$guide_file" ]]; then
    printf '\n## Mosaic PRD Guide (Authoritative Rules)\n\n'
    cat "$guide_file"
  fi

  # Include the template as reference
  if [[ -f "$template_file" ]]; then
    printf '\n## PRD Template Reference\n\n```markdown\n'
    cat "$template_file"
    printf '\n```\n'
  fi
}
