#!/usr/bin/env python3
"""Stand-in for `opencode run --format json` that follows the real JSONL protocol."""

import json
import os
import sys
import time

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _common import emit, log_call, opt, reject_flags, reply_text, sample, tool_reply  # noqa: E402

args = sys.argv[1:]
if args[:1] != ["run"]:
    sys.exit(2)
if "--help" in args:
    print("Usage: opencode run [message..]\n  --format json\n  --model <provider/model>\n  --thinking\n  --auto")
    sys.exit(0)

reject_flags(args, "error: unknown option '{flag}'")
prompt = sys.stdin.read()
files = [args[i + 1] for i, a in enumerate(args) if a in ("--file", "-f")]
log_call({"cli": "opencode", "argv": args, "prompt": prompt, "images": len(files), "cwd": os.getcwd(),
          "env_has_openai_key": "OPENAI_API_KEY" in os.environ,
          "project_config_disabled": os.environ.get("OPENCODE_DISABLE_PROJECT_CONFIG") == "1"})

model = opt(args, "--model") or "opencode/default"
session = "ses_123"
step = 0


def part(kind, mid, **fields):
    return {"type": kind, "sessionID": session, "part": {"messageID": mid, "sessionID": session, **fields}}


def finish(mid, input_tokens, output_tokens, reasoning_tokens=0, cached=0, cost=0.0):
    emit(part("step_finish", mid, type="step-finish", reason="stop",
              tokens={"input": input_tokens, "output": output_tokens, "reasoning": reasoning_tokens,
                      "cache": {"read": cached, "write": 0}}, cost=cost))


if "SLOW" in prompt:
    time.sleep(30)
if "FAIL" in prompt:
    emit({"type": "error", "sessionID": session,
          "error": {"type": "provider.error", "message": "You've hit your usage limit."}})
    sys.exit(1)
if "CRASH" in prompt:
    sys.stderr.write("boom: something broke\n")
    sys.exit(3)

emit({"type": "step_start", "sessionID": session, "part": {"type": "step-start"}})

agent = "--auto" in args and "AGENT" in prompt
if agent:
    step += 1
    emit(part("text", "msg-1", type="text", text="Let me look around."))
    emit(part("tool_use", "msg-1", type="tool", tool="shell",
              state={"status": "completed", "input": {"command": "ls -la"}}))
    finish("msg-1", 100, 5, cached=20, cost=0.001)
    emit({"type": "step_start", "sessionID": session, "part": {"type": "step-start"}})

if "--thinking" in args and "THINK" in prompt:
    emit(part("reasoning", "msg-2", type="reasoning", text="Considering the question."))

if '"tool_calls"' in prompt and "# Functions" in prompt:
    names = []
    for line in prompt.splitlines():
        line = line.strip()
        if line.startswith('{"name"'):
            try:
                names.append(json.loads(line)["name"])
            except ValueError:
                pass
    text = json.dumps(tool_reply(prompt, names, args_as_string=False))
elif "# Output format" in prompt and "JSON Schema" in prompt:
    start = prompt.find("{", prompt.find("JSON Schema"))
    schema = None
    if start != -1:
        try:
            schema = json.JSONDecoder().raw_decode(prompt, start)[0]
        except ValueError:
            schema = None
    text = json.dumps(sample(schema) if schema else {})
else:
    text = reply_text(model, prompt)

emit(part("text", "msg-2", type="text", text=text))
finish("msg-2", 40 if agent else 100, 9,
       reasoning_tokens=4 if "--thinking" in args and "THINK" in prompt else 0,
       cached=5 if agent else 20, cost=0.002 if agent else 0.0012)
