"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const cors_1 = __importDefault(require("cors"));
const job_store_1 = require("./job-store");
const agent_runner_1 = require("./agent-runner");
const agents_1 = require("./agents");
const app = (0, express_1.default)();
app.use((0, cors_1.default)());
app.use(express_1.default.json());
const PORT = process.env.PORT || 3333;
// ---------------------------------------------------------------------------
// Build ToolContext from environment variables
// ---------------------------------------------------------------------------
function buildContext(repo) {
    const workspaceRoot = repo
        ? `${process.env.WORKSPACE_BASE || '/workspaces'}/${repo.replace('/', '_')}`
        : (process.env.WORKSPACE_BASE || '/workspaces/default');
    return {
        workspaceRoot,
        gitea: {
            apiUrl: process.env.GITEA_API_URL || '',
            apiToken: process.env.GITEA_API_TOKEN || '',
            username: process.env.GITEA_USERNAME || ''
        },
        coolify: {
            apiUrl: process.env.COOLIFY_API_URL || '',
            apiToken: process.env.COOLIFY_API_TOKEN || ''
        }
    };
}
// ---------------------------------------------------------------------------
// Routes
// ---------------------------------------------------------------------------
// Health check
app.get('/health', (_req, res) => {
    res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
// List available agents
app.get('/api/agents', (_req, res) => {
    const agents = Object.values(agents_1.AGENTS).map(a => ({
        name: a.name,
        description: a.description,
        tools: a.tools.map(t => t.name)
    }));
    res.json(agents);
});
// Submit a new job
app.post('/api/agent/run', async (req, res) => {
    const { agent: agentName, task, repo } = req.body;
    if (!agentName || !task) {
        res.status(400).json({ error: '"agent" and "task" are required' });
        return;
    }
    const agentConfig = agents_1.AGENTS[agentName];
    if (!agentConfig) {
        const available = Object.keys(agents_1.AGENTS).join(', ');
        res.status(400).json({ error: `Unknown agent "${agentName}". Available: ${available}` });
        return;
    }
    const job = (0, job_store_1.createJob)(agentName, task, repo);
    res.status(202).json({ jobId: job.id, status: job.status });
    // Run agent asynchronously
    const ctx = buildContext(repo);
    (0, agent_runner_1.runAgent)(job, agentConfig, task, ctx)
        .then(result => {
        (0, job_store_1.updateJob)(job.id, {
            status: 'completed',
            result: result.finalText,
            progress: `Done — ${result.turns} turns, ${result.toolCallCount} tool calls`
        });
    })
        .catch(err => {
        (0, job_store_1.updateJob)(job.id, {
            status: 'failed',
            error: err instanceof Error ? err.message : String(err),
            progress: 'Agent failed'
        });
    });
});
// Check job status
app.get('/api/jobs/:id', (req, res) => {
    const job = (0, job_store_1.getJob)(req.params.id);
    if (!job) {
        res.status(404).json({ error: 'Job not found' });
        return;
    }
    res.json(job);
});
// List recent jobs
app.get('/api/jobs', (req, res) => {
    const limit = parseInt(req.query.limit || '20', 10);
    res.json((0, job_store_1.listJobs)(limit));
});
// Gitea webhook endpoint — triggers agent from a push/issue event
app.post('/webhook/gitea', (req, res) => {
    const event = req.headers['x-gitea-event'];
    const body = req.body;
    // Verify secret if configured
    const webhookSecret = process.env.WEBHOOK_SECRET;
    if (webhookSecret) {
        const sig = req.headers['x-gitea-signature'];
        if (!sig || sig !== webhookSecret) {
            res.status(401).json({ error: 'Invalid webhook signature' });
            return;
        }
    }
    let task = null;
    let agentName = 'Coder';
    let repo;
    if (event === 'issues' && body.action === 'opened') {
        const issue = body.issue;
        repo = `${body.repository?.owner?.login}/${body.repository?.name}`;
        const labels = (issue.labels || []).map((l) => l.name);
        if (labels.includes('agent:pm')) {
            agentName = 'PM';
        }
        else if (labels.includes('agent:marketing')) {
            agentName = 'Marketing';
        }
        else {
            agentName = 'Coder';
        }
        task = `Resolve this GitHub issue:\n\nTitle: ${issue.title}\n\nDescription:\n${issue.body || '(no description)'}`;
    }
    else if (event === 'push') {
        // Optionally trigger on push — useful for CI-style automation
        res.json({ ignored: true, reason: 'push events not auto-processed' });
        return;
    }
    else {
        res.json({ ignored: true, event });
        return;
    }
    if (!task) {
        res.json({ ignored: true });
        return;
    }
    const agentConfig = agents_1.AGENTS[agentName];
    const job = (0, job_store_1.createJob)(agentName, task, repo);
    res.status(202).json({ jobId: job.id, agent: agentName, event });
    const ctx = buildContext(repo);
    (0, agent_runner_1.runAgent)(job, agentConfig, task, ctx)
        .then(result => {
        (0, job_store_1.updateJob)(job.id, {
            status: 'completed',
            result: result.finalText,
            progress: `Done — ${result.turns} turns, ${result.toolCallCount} tool calls`
        });
    })
        .catch(err => {
        (0, job_store_1.updateJob)(job.id, {
            status: 'failed',
            error: err instanceof Error ? err.message : String(err),
            progress: 'Agent failed'
        });
    });
});
// ---------------------------------------------------------------------------
// Error handler
// ---------------------------------------------------------------------------
app.use((err, _req, res, _next) => {
    console.error(err.stack);
    res.status(500).json({ error: err.message });
});
// ---------------------------------------------------------------------------
// Start
// ---------------------------------------------------------------------------
app.listen(PORT, () => {
    console.log(`AgentRunner listening on port ${PORT}`);
    console.log(`Agents available: ${Object.keys(agents_1.AGENTS).join(', ')}`);
    if (!process.env.GOOGLE_API_KEY) {
        console.warn('WARNING: GOOGLE_API_KEY is not set — agents will fail');
    }
});
