#!/usr/bin/env python3
"""Create simultaneous, prefix-disjoint requests for a fixed decode batch."""

from __future__ import annotations

import argparse
import json
from pathlib import Path


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser()
    parser.add_argument("--model", type=Path, required=True)
    parser.add_argument("--batch", type=int, required=True)
    parser.add_argument("--input-tokens", type=int, default=2048)
    parser.add_argument("--output-tokens", type=int, default=128)
    parser.add_argument("--output", type=Path, required=True)
    return parser.parse_args()


def main() -> None:
    args = parse_args()
    if min(args.batch, args.input_tokens, args.output_tokens) <= 0:
        raise ValueError("batch and token counts must be positive")
    if args.input_tokens + args.output_tokens > 40960:
        raise ValueError("request exceeds the server max model length")

    from transformers import AutoTokenizer

    tokenizer = AutoTokenizer.from_pretrained(args.model, trust_remote_code=True)
    special = set(tokenizer.all_special_ids)
    candidates = [
        token for token in range(tokenizer.vocab_size) if token not in special
    ]
    if len(candidates) < args.batch + 1:
        raise ValueError("tokenizer has too few non-special token IDs")

    base = candidates[0]
    args.output.parent.mkdir(parents=True, exist_ok=True)
    with args.output.open("w") as output:
        for index in range(args.batch):
            row = {
                "source_index": index,
                "arrived_at": 0.0,
                "input_length": args.input_tokens,
                "output_length": args.output_tokens,
                "session_id": index,
                "runtime_block_ids": [],
                "body": {
                    "prompt": [
                        candidates[index + 1],
                        *([base] * (args.input_tokens - 1)),
                    ],
                    "min_tokens": args.output_tokens,
                    "max_tokens": args.output_tokens,
                    "ignore_eos": True,
                },
            }
            output.write(json.dumps(row, separators=(",", ":")) + "\n")


if __name__ == "__main__":
    main()
