#!/usr/bin/env bash
set -euo pipefail

# ============================================================
# XH-1 Research Harness
# Pure Bash / OpenAI-compatible API
# ============================================================

ROOT="${XH1_RESEARCH_ROOT:-research}"
STATE="${ROOT}/.xh1"
CONFIG="${XH1_RESEARCH_CONFIG:-xh1-research.conf}"

mkdir -p "$STATE"/{logs,responses}

# ------------------------------------------------------------
# Defaults
# ------------------------------------------------------------

API_BASE_URL="${API_BASE_URL:-https://api.openai.com/v1}"
API_KEY_ENV="${API_KEY_ENV:-OPENAI_API_KEY}"
MODEL="${MODEL:-}"

MAX_RETRIES="${MAX_RETRIES:-3}"
DELAY_SECONDS="${DELAY_SECONDS:-5}"
MAX_ITERATIONS="${MAX_ITERATIONS:-0}"

REVIEW_ENABLED="${REVIEW_ENABLED:-true}"
AUTO_COMMIT="${AUTO_COMMIT:-false}"

# ------------------------------------------------------------
# Helpers
# ------------------------------------------------------------

die() {
    echo "ERROR: $*" >&2
    exit 1
}

log() {
    local msg="$*"
    echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] $msg" \
        | tee -a "$STATE/logs/harness.log"
}

require() {
    command -v "$1" >/dev/null 2>&1 ||
        die "Required command not found: $1"
}

load_config() {
    if [[ -f "$CONFIG" ]]; then
        # shellcheck disable=SC1090
        source "$CONFIG"
    fi
}

require_dependencies() {
    require bash
    require curl
    require jq
}

get_api_key() {
    local key="${!API_KEY_ENV:-}"

    [[ -n "$key" ]] ||
        die "API key missing. Set ${API_KEY_ENV}."

    printf '%s' "$key"
}

timestamp() {
    date -u '+%Y%m%dT%H%M%SZ'
}

# ------------------------------------------------------------
# Configuration
# ------------------------------------------------------------

init_config() {

    if [[ -f "$CONFIG" ]]; then
        echo "Configuration already exists:"
        echo "  $CONFIG"
        return
    fi

    cat > "$CONFIG" <<'EOF'
# ============================================================
# XH-1 Research Harness Configuration
# ============================================================

# OpenAI-compatible API
API_BASE_URL="https://api.openai.com/v1"

# Environment variable containing API key
API_KEY_ENV="OPENAI_API_KEY"

# Model name
MODEL=""

# Research behavior
MAX_RETRIES=3
DELAY_SECONDS=5
MAX_ITERATIONS=0

# Run reviewer after researcher
REVIEW_ENABLED=true

# Automatically create git commits
AUTO_COMMIT=false
EOF

    echo "Created $CONFIG"
}

# ------------------------------------------------------------
# API
# ------------------------------------------------------------

api_call() {

    local system_prompt="$1"
    local user_prompt="$2"
    local output="$3"

    local key
    key="$(get_api_key)"

    [[ -n "$MODEL" ]] ||
        die "MODEL is not configured."

    local payload

    payload="$(
        jq -n \
            --arg model "$MODEL" \
            --arg system "$system_prompt" \
            --arg user "$user_prompt" \
            '{
                model: $model,
                messages: [
                    {
                        role: "system",
                        content: $system
                    },
                    {
                        role: "user",
                        content: $user
                    }
                ],
                temperature: 0.2
            }'
    )"

    local attempt=1

    while (( attempt <= MAX_RETRIES )); do

        if curl \
            --fail \
            --silent \
            --show-error \
            --connect-timeout 30 \
            --max-time 1800 \
            -H "Authorization: Bearer ${key}" \
            -H "Content-Type: application/json" \
            "${API_BASE_URL%/}/chat/completions" \
            -d "$payload" \
            > "${output}.json"
        then

            if jq -er \
                '.choices[0].message.content' \
                "${output}.json" \
                > "$output"
            then
                return 0
            fi
        fi

        log "API attempt $attempt failed."

        sleep $((attempt * attempt))

        ((attempt++))
    done

    return 1
}

# ------------------------------------------------------------
# Research discovery
# ------------------------------------------------------------

is_research_file() {

    [[ "$1" == *.md ]] &&
    [[ "$1" != "$STATE"/* ]]
}

is_soon() {

    grep -qE \
        '^SOON[[:space:]]*$' \
        "$1"
}

find_next_task() {

    while IFS= read -r -d '' file; do

        if is_research_file "$file" &&
           is_soon "$file"
        then
            printf '%s\n' "$file"
            return 0
        fi

    done < <(
        find "$ROOT" \
            -type f \
            -name '*.md' \
            -not -path "$STATE/*" \
            -print0
    )

    return 1
}

# ------------------------------------------------------------
# Research context
# ------------------------------------------------------------

build_context() {

    local file="$1"

    local relative
    relative="${file#"$ROOT"/}"

    local area
    area="${relative%%/*}"

    cat <<EOF
PROJECT
=======

Name:
XH-1

Architecture:
Custom 128-core RISC-V CPU

Research repository:
XH-1 Research

Research document:
$file

Research area:
$area


CURRENT DOCUMENT
================

EOF

    cat "$file"

    cat <<EOF


RELATED DOCUMENTS
=================

EOF

    find "$ROOT/$area" \
        -maxdepth 1 \
        -type f \
        -name '*.md' \
        ! -path "$file" \
        | sort \
        | head -20 \
        | while read -r related; do

            echo
            echo "----- $related -----"
            cat "$related"

        done
}

# ------------------------------------------------------------
# Research prompt
# ------------------------------------------------------------

research_system_prompt() {

cat <<'EOF'
You are a senior computer architecture researcher working on XH-1.

XH-1 is a custom 128-core RISC-V processor.

Your job is to perform rigorous technical research for exactly one assigned research topic.

You are NOT allowed to invent:

- sources
- papers
- URLs
- measurements
- benchmarks
- experiments
- hardware capabilities
- implementation details

Clearly distinguish:

FACT
ASSUMPTION
PROPOSAL
RECOMMENDATION
OPEN QUESTION

Prefer primary and authoritative sources.

For RISC-V topics, prioritize official RISC-V specifications.

For architecture topics, consider academic literature, processor manuals,
technical papers, and reputable engineering documentation.

The fact that XH-1 contains 128 cores is extremely important.

Do not provide generic CPU advice without explaining how it affects
a 128-core processor.

Research should investigate multiple alternatives where applicable.

Consider:

- performance
- latency
- bandwidth
- area
- power
- scalability
- implementation complexity
- verification complexity
- software implications
- failure modes
- future extensibility

You are researching the architecture.

Do not assume an architectural decision has already been made.

If evidence is insufficient, explicitly say:

INSUFFICIENT EVIDENCE

Do not force a recommendation when the evidence does not justify one.
EOF
}

research_user_prompt() {

    local file="$1"

    build_context "$file"

    cat <<'EOF'

RESEARCH TASK
=============

Investigate the assigned topic thoroughly.

Produce a technically detailed Markdown research document.

Use this structure where applicable:

# Topic

## Status

## Abstract

## Research Question

## Background

## Existing Approaches

## Alternative Designs

## Comparison

## Advantages

## Disadvantages

## XH-1 Considerations

## 128-Core Scalability

## Performance Considerations

## Implementation Considerations

## Verification Considerations

## Recommendation

## Confidence

## Open Questions

## Sources

Do not include conversational commentary.

The output must be suitable for insertion into the research repository.
EOF
}

# ------------------------------------------------------------
# Reviewer
# ------------------------------------------------------------

review_system_prompt() {

cat <<'EOF'
You are the independent technical reviewer for the XH-1
128-core RISC-V processor research project.

Your job is to aggressively review another research agent's work.

Check for:

1. factual errors
2. unsupported claims
3. hallucinated sources
4. incorrect RISC-V information
5. missing alternatives
6. weak reasoning
7. contradictions
8. unexplained assumptions
9. failure to consider 128 cores
10. unrealistic implementation claims
11. unsupported performance claims
12. missing verification concerns
13. unjustified recommendations

Do not rewrite the research.

Return exactly:

VERDICT: PASS

or:

VERDICT: FAIL

Then provide:

ISSUES:
- ...

REQUIRED_FIXES:
- ...

CONFIDENCE: HIGH/MEDIUM/LOW
EOF
}

review_document() {

    local document="$1"
    local output="$2"

    api_call \
        "$(review_system_prompt)" \
        "$(cat "$document")" \
        "$output"
}

# ------------------------------------------------------------
# File safety
# ------------------------------------------------------------

replace_soon() {

    local target="$1"
    local replacement="$2"

    # Make absolutely sure we are still replacing a SOON document.

    if ! is_soon "$target"; then
        die "Refusing to overwrite modified document: $target"
    fi

    local temporary

    temporary="$(mktemp)"

    cat "$replacement" > "$temporary"

    mv "$temporary" "$target"
}

# ------------------------------------------------------------
# Git
# ------------------------------------------------------------

git_commit() {

    local file="$1"

    [[ "$AUTO_COMMIT" == "true" ]] ||
        return 0

    git rev-parse \
        --is-inside-work-tree \
        >/dev/null 2>&1 ||
        return 0

    git add "$file"

    local title

    title="$(
        basename "$file" .md |
        tr '-' ' '
    )"

    git commit \
        -m "research: ${title}" \
        || true
}

# ------------------------------------------------------------
# Research one document
# ------------------------------------------------------------

run_one() {

    local file="${1:-}"

    if [[ -z "$file" ]]; then
        file="$(find_next_task || true)"
    fi

    [[ -n "$file" ]] ||
        {
            echo "No incomplete research topics."
            return 0
        }

    [[ -f "$file" ]] ||
        die "Research file does not exist: $file"

    log "Starting research: $file"

    local id
    id="$(timestamp)_$(basename "$file" .md)"

    local response
    response="$STATE/responses/${id}.md"

    log "Running researcher."

    if ! api_call \
        "$(research_system_prompt)" \
        "$(research_user_prompt "$file")" \
        "$response"
    then

        log "Research agent failed."

        return 1
    fi

    log "Research completed."

    # --------------------------------------------------------
    # Review
    # --------------------------------------------------------

    if [[ "$REVIEW_ENABLED" == "true" ]]; then

        local review
        review="${response}.review"

        log "Running reviewer."

        if ! review_document \
            "$response" \
            "$review"
        then

            log "Reviewer failed."

            return 1
        fi

        local verdict

        verdict="$(
            grep -m1 '^VERDICT:' "$review" |
            tr -d '\r'
        )"

        echo
        echo "=========================================="
        echo "RESEARCH REVIEW"
        echo "=========================================="
        cat "$review"
        echo "=========================================="
        echo

        if [[ "$verdict" != "VERDICT: PASS" ]]; then

            log "Research rejected by reviewer."

            return 2
        fi

        log "Research passed review."

    fi

    # --------------------------------------------------------
    # Replace SOON
    # --------------------------------------------------------

    replace_soon "$file" "$response"

    printf '%s\t%s\t%s\n' \
        "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
        "completed" \
        "$file" \
        >> "$STATE/state.tsv"

    git_commit "$file"

    log "Completed: $file"

    return 0
}

# ------------------------------------------------------------
# Loop
# ------------------------------------------------------------

run_loop() {

    local iteration=0

    while true; do

        if (( MAX_ITERATIONS > 0 &&
              iteration >= MAX_ITERATIONS )); then

            log "Maximum iterations reached."

            break
        fi

        local file

        file="$(find_next_task || true)"

        if [[ -z "$file" ]]; then

            log "No SOON documents remain."

            break
        fi

        echo
        echo "=========================================="
        echo "XH-1 RESEARCH ITERATION $((iteration + 1))"
        echo "=========================================="
        echo
        echo "Topic:"
        echo "  $file"
        echo

        if run_one "$file"; then

            log "Iteration successful."

        else

            log "Iteration failed."

            echo
            echo "Research failed."
            echo "The document was NOT modified."
            echo

        fi

        ((iteration += 1))

        sleep "$DELAY_SECONDS"

    done
}

# ------------------------------------------------------------
# Status
# ------------------------------------------------------------

status() {

    [[ -d "$ROOT" ]] ||
        die "Research directory not found: $ROOT"

    local total
    local soon
    local researched

    total="$(
        find "$ROOT" \
            -type f \
            -name '*.md' \
            -not -path "$STATE/*" |
        wc -l |
        tr -d ' '
    )"

    soon="$(
        grep -RIl \
            '^SOON[[:space:]]*$' \
            "$ROOT" \
            --include='*.md' \
            --exclude-dir='.xh1' \
            2>/dev/null |
        wc -l |
        tr -d ' '
    )"

    researched=$((total - soon))

    echo
    echo "╔══════════════════════════════════════╗"
    echo "║        XH-1 RESEARCH STATUS         ║"
    echo "╚══════════════════════════════════════╝"
    echo

    printf "  Total documents : %s\n" "$total"
    printf "  Research ready  : %s\n" "$researched"
    printf "  Remaining SOON  : %s\n" "$soon"

    if (( total > 0 )); then

        awk \
            -v done="$researched" \
            -v total="$total" \
            'BEGIN {
                printf "  Progress        : %.1f%%\n",
                (done / total) * 100
            }'

    fi

    echo

    echo "Next topic:"

    find_next_task || echo "  None"

    echo
}

# ------------------------------------------------------------
# Review command
# ------------------------------------------------------------

review_command() {

    local file="${1:-}"

    [[ -n "$file" ]] ||
        die "Usage: $0 review <file>"

    [[ -f "$file" ]] ||
        die "File does not exist: $file"

    local output

    output="$STATE/responses/manual_review_$(timestamp).txt"

    review_document "$file" "$output"

    cat "$output"
}

# ------------------------------------------------------------
# Initialization
# ------------------------------------------------------------

initialize() {

    mkdir -p \
        "$STATE/logs" \
        "$STATE/responses"

    touch \
        "$STATE/state.tsv"

    init_config

    echo
    echo "XH-1 research harness initialized."
    echo
    echo "Configuration:"
    echo "  $CONFIG"
    echo
    echo "State:"
    echo "  $STATE"
    echo
}

# ------------------------------------------------------------
# Help
# ------------------------------------------------------------

help() {

cat <<'EOF'

XH-1 RESEARCH HARNESS
=====================

Pure Bash autonomous research system.

USAGE

  ./xh1-research <command>


COMMANDS

  init

      Initialize the harness.

  status

      Show research progress.

  next

      Show the next SOON document.

  run

      Research the next topic.

  run <file>

      Research a specific document.

  run-all

      Continuously research every SOON document.

  loop

      Alias for run-all.

  resume

      Resume autonomous research.

  review <file>

      Manually review a research document.

  help

      Show this help.


EXAMPLES

  ./xh1-research init

  ./xh1-research status

  ./xh1-research next

  ./xh1-research run

  ./xh1-research run research/04-128-core/topology.md

  ./xh1-research run-all

  ./xh1-research review research/05-memory/cache-coherency.md


ENVIRONMENT

  XH1_RESEARCH_ROOT

      Research directory.

      Default:
          research


  XH1_RESEARCH_CONFIG

      Configuration file.

      Default:
          xh1-research.conf


CONFIGURATION

  API_BASE_URL

      OpenAI-compatible API base.

  API_KEY_ENV

      Environment variable containing API key.

  MODEL

      Model identifier.

  MAX_RETRIES

      API retry count.

  DELAY_SECONDS

      Delay between research iterations.

  MAX_ITERATIONS

      Maximum autonomous iterations.

      0 = unlimited.

  REVIEW_ENABLED

      Enable reviewer agent.

  AUTO_COMMIT

      Automatically commit completed research.


SAFETY

  Existing research is never overwritten.

  A document is only modified if it still contains
  a standalone SOON marker.

  Git push is never performed automatically.


EOF
}

# ------------------------------------------------------------
# Main
# ------------------------------------------------------------

load_config
require_dependencies

COMMAND="${1:-status}"

case "$COMMAND" in

    init)
        initialize
        ;;

    status)
        status
        ;;

    next)
        find_next_task || true
        ;;

    run)
        run_one "${2:-}"
        ;;

    run-all|loop|resume)
        run_loop
        ;;

    review)
        review_command "${2:-}"
        ;;

    help|-h|--help)
        help
        ;;

    *)
        die "Unknown command: $COMMAND. Use --help."

esac
