"""Seed a dedicated demo database and save a private MCP client config.

Run with the Python environment that contains redis-mcp-server. ADMIN_REDIS_URL
defaults to loopback Redis on port 6391. This creates a Redis ACL user and two
demo keys; it refuses to replace an existing user or existing demo keys.
"""
import json
import os
from pathlib import Path
import secrets
import sys
from urllib.parse import urlsplit

import redis


def main():
    url = os.environ.get("ADMIN_REDIS_URL", "redis://127.0.0.1:6391/0")
    parts = urlsplit(url)
    if parts.scheme not in ("redis", "rediss") or not parts.hostname:
        raise SystemExit("ADMIN_REDIS_URL must be a redis:// or rediss:// URL.")
    if parts.query:
        raise SystemExit("Use a URL without query parameters; configure custom TLS certificates separately.")
    host = parts.hostname
    port = parts.port or 6379
    db = int(parts.path.lstrip("/") or "0")
    user = "mcp_reader"
    output = Path("mcp.local.json")
    executable = Path(sys.executable).parent / ("redis-mcp-server.exe" if os.name == "nt" else "redis-mcp-server")
    if not executable.is_file():
        raise SystemExit("Install requirements.txt into this Python environment first.")
    if output.exists():
        raise SystemExit("mcp.local.json already exists; keep or move it before creating another demo.")
    admin = redis.Redis.from_url(url, decode_responses=True, socket_connect_timeout=10, socket_timeout=10)
    try:
        admin.ping()
        if admin.acl_getuser(user) is not None:
            raise SystemExit("mcp_reader already exists. Use a fresh demo instance; no changes made.")
        if admin.exists("mcpdemo:status", "mcpdemo:session:42"):
            raise SystemExit("Demo keys already exist. Use a fresh demo instance; no changes made.")
        password = secrets.token_urlsafe(32)
        admin.execute_command("ACL", "SETUSER", user, "reset", "on", ">" + password,
                              "~mcpdemo:*", "-@all", "+ping", "+get", "+hget", "+hgetall", "+type", "+ttl")
        pipe = admin.pipeline()
        pipe.set("mcpdemo:status", "ready", ex=3600, nx=True)
        pipe.hset("mcpdemo:session:42", mapping={"user": "demo-user", "language": "english"})
        pipe.expire("mcpdemo:session:42", 3600)
        pipe.execute()
        args = ["--host", host, "--port", str(port), "--db", str(db)]
        if parts.scheme == "rediss":
            args += ["--ssl", "--ssl-cert-reqs", "required"]
        config = {"mcpServers": {"redis-demo": {"command": str(executable), "args": args,
                    "env": {"REDIS_USERNAME": user, "REDIS_PWD": password}}}}
        fd = os.open(output, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
        with os.fdopen(fd, "w") as handle:
            json.dump(config, handle, indent=2)
            handle.write("\n")
        print("Created two demo keys with a 3600-second TTL and a restricted mcp_reader user.")
        print("Saved mcp.local.json with the reader credential. Keep it private and out of Git.")
        print("Merge its redis-demo entry into your MCP client config. Do not replace other servers.")
    except redis.RedisError as exc:
        # Avoid printing connection URLs, which can carry the administrator password.
        raise SystemExit(f"Redis setup failed ({type(exc).__name__}). Check connection and ACL permissions.") from None
    finally:
        admin.close()


if __name__ == "__main__":
    main()
