#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Example AriGPT API requests chain"""

import hashlib
import sys
import time
import typing as t
from pprint import pprint
from warnings import filterwarnings as filter_warnings

import requests  # type: ignore

API: t.Final[str] = "http://127.0.0.1:5000/gpt/api"  # or https://ari.lt/gpt/api
SESSION: t.Final[requests.Session] = requests.Session()


def get(api: str) -> t.Any:
    """Make a GET API call"""

    time.sleep(0.5)  # Sleep to avoid rate limiting

    response: requests.Response = SESSION.get(f"{API}{api}")

    if not response.ok:
        print(response.text, file=sys.stderr)
        print(f"Exiting due to error {response.status_code}", file=sys.stderr)
        sys.exit()

    return response.json()


def post(api: str, data: t.Any) -> t.Any:
    """Make a POST API call"""

    time.sleep(0.5)  # Sleep to avoid rate limiting

    response: requests.Response = SESSION.post(
        f"{API}{api}",
        json=data,
        headers={"Content-Type": "application/json"},
    )

    if not response.ok:
        print(response.text, file=sys.stderr)
        print(f"Exiting due to error {response.status_code}", file=sys.stderr)
        sys.exit()

    return response.json()


def solve_pow(nonce: str, difficulty: int) -> str:
    """Solve Proof-of-Work"""

    prefix: str = "0" * difficulty
    solution: int = 0

    while True:
        if (
            hashlib.sha256((nonce + str(solution)).encode("ascii"))
            .hexdigest()
            .startswith(prefix)
        ):
            return str(solution)
        solution += 1


def main() -> int:
    """entry / main function"""

    print("Files:")
    pprint(get("/files"))

    print("Stats:")
    pprint(get("/stats"))

    config: t.Dict[str, t.Any] = get(f"/config")

    print("Configuration:")
    pprint(config)
    print("Cookies:", SESSION.cookies)

    print("Solving PoW...")
    solution: str = solve_pow(config["nonce"], config["difficulty"])
    print(f"Solution: {solution}")

    print("Querying AriGPT...")

    question: t.Dict[str, str] = post(
        "/query",
        {
            "solution": solution,
            "prompt": f"This is an example prompt @ {time.time()}",
        },
    )

    print(f"Question ID: {question['id']}")
    input("Press enter to continue (GET answer, page)...")

    print("Answer content:")
    pprint(get(f"/answer/{question['id']}"))

    print("Page content:")
    pprint(get("/page/1"))

    return 0


if __name__ == "__main__":
    assert main.__annotations__.get("return") is int, "main() should return an integer"

    filter_warnings("error", category=Warning)
    raise SystemExit(main())
