const fs = require('fs');
const path = require('path');

/**
 * GitHub Actions adapter.
 *
 * Generates `.github/workflows/baldart-<name>.yml` with a `schedule` trigger
 * and a `workflow_dispatch` trigger for manual runs. The workflow checks out
 * the repo, sets up Node, installs Claude Code, and invokes the agent via
 * the headless Claude CLI.
 *
 * Requires the user to set the `ANTHROPIC_API_KEY` secret in the repo.
 */
class GitHubActionsAdapter {
  constructor(cwd = process.cwd()) {
    this.cwd = cwd;
  }

  get name() { return 'github-actions'; }
  get label() { return 'GitHub Actions'; }
  get description() {
    return 'Schedules via a workflow with cron + workflow_dispatch. Requires the ANTHROPIC_API_KEY secret.';
  }

  workflowDir() {
    return path.join(this.cwd, '.github', 'workflows');
  }

  workflowPath(name) {
    return path.join(this.workflowDir(), `baldart-${name}.yml`);
  }

  install(spec) {
    if (!fs.existsSync(this.workflowDir())) {
      fs.mkdirSync(this.workflowDir(), { recursive: true });
    }
    const yml = this._renderWorkflow(spec);
    fs.writeFileSync(this.workflowPath(spec.name), yml);
    // review_engine: codex is cron-only (no Codex plugin/auth in CI) — this backend always uses claude.
    const codexWarn = String(spec.review_engine || '').toLowerCase() === 'codex'
      ? [`⚠ review_engine: codex is NOT supported on github-actions (no Codex plugin/auth in CI) — this routine runs on the claude engine.`]
      : [];
    return {
      backend: this.name,
      artifacts: [path.relative(this.cwd, this.workflowPath(spec.name))],
      followup: [
        ...codexWarn,
        `Set the repository secret ANTHROPIC_API_KEY in GitHub.`,
        `Commit and push .github/workflows/baldart-${spec.name}.yml to enable the schedule.`,
        `Manual test: gh workflow run baldart-${spec.name}.yml`
      ]
    };
  }

  uninstall(name) {
    const p = this.workflowPath(name);
    if (fs.existsSync(p)) fs.unlinkSync(p);
    return {
      backend: this.name,
      followup: [
        `Commit the removal of .github/workflows/baldart-${name}.yml to disable the schedule.`
      ]
    };
  }

  detect(name) {
    return fs.existsSync(this.workflowPath(name));
  }

  _renderWorkflow(spec) {
    const cron = spec.schedule.cron;
    const promptIndented = spec.prompt.split('\n').map(l => '            ' + l).join('\n');
    const outputPath = (spec.output && spec.output.path) || `docs/reports/{{YYYYMMDD}}-${spec.name}.md`;
    const commitEnabled = spec.output && spec.output.commit && spec.output.commit.enabled;
    const commitPrefix = (spec.output && spec.output.commit && spec.output.commit.prefix) || `[${spec.name.toUpperCase()}]`;

    return `# Generated by BALDART (v${require('../../../package.json').version}) — npx baldart routines
# Routine: ${spec.name}
# ${spec.description}

name: BALDART ${spec.name}

on:
  schedule:
    - cron: '${cron}'   # ${spec.schedule.cadence_label || 'scheduled'}
  workflow_dispatch:    # manual trigger from the Actions tab

permissions:
  contents: write
  pull-requests: write

jobs:
  run:
    runs-on: ubuntu-latest
    timeout-minutes: 60
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Claude Code CLI
        run: npm install -g @anthropic-ai/claude-code

      - name: Run ${spec.name}
        env:
          ANTHROPIC_API_KEY: \${{ secrets.ANTHROPIC_API_KEY }}
          # Marks this as an unattended (no-human) run. The /baldart-update
          # skill (and any other autonomy-aware skill) auto-detects this and
          # switches to non-interactive mode — no chat confirmations, safe
          # guardrails (STOP on custom divergence / conflicts, never forces a
          # destructive merge). Inherited by the \`claude\` process and every
          # child Bash it spawns.
          BALDART_AUTONOMOUS: '1'
        run: |
          DATE=$(date -u +%Y%m%d)
          OUT_PATH="${outputPath}"
          OUT_PATH="\${OUT_PATH//\\{\\{YYYYMMDD\\}\\}/$DATE}"
          mkdir -p "$(dirname "$OUT_PATH")"

          claude --print --output-format json --mode bypassPermissions \\
            --agent ${spec.agent} \\
            > /tmp/claude-output.json <<'PROMPT'
${promptIndented}
          PROMPT

          # Persist the output if the agent did not already write to disk
          if [ ! -s "$OUT_PATH" ]; then
            jq -r '.result // .' /tmp/claude-output.json > "$OUT_PATH" || \\
              cp /tmp/claude-output.json "$OUT_PATH"
          fi
${commitEnabled ? `
      - name: Commit report
        run: |
          git config user.name "baldart-routine"
          git config user.email "baldart-routine@users.noreply.github.com"
          git add -A
          if ! git diff --staged --quiet; then
            git commit -m "${commitPrefix} \${{ github.workflow }} run \$(date -u +%Y-%m-%d)"
            git push
          else
            echo "No changes to commit."
          fi
` : ''}`;
  }
}

module.exports = GitHubActionsAdapter;
