# -*- coding: utf-8 -*-
"""CRYPTTRON local signer — the optional sign-in route.

For people whose wallet cannot sign a message, or who would simply rather use a
terminal. Everything happens on YOUR machine: this script never contacts
Crypttron, and your private key is never transmitted anywhere.

One-time setup:
    pip install embit

Get your public key from a private key:
    python crypttron_sign.py --pubkey YOUR_PRIVATE_KEY_HEX_OR_WIF

Sign the line the site gives you:
    python crypttron_sign.py --sign "CRYPTTRON-KEY|..." --key YOUR_PRIVATE_KEY

Then paste the printed signature back into the site.

Note the quotes around the line: it contains | characters, which a shell reads
as pipes if left unquoted. That single detail causes most failed attempts.
"""
from __future__ import annotations

import argparse
import hashlib
import sys


def _load_key(raw: str):
    """Accept hex or WIF, so people don't have to convert formats first."""
    from embit import ec
    raw = raw.strip()
    if raw.startswith(("K", "L", "5", "c", "9")) and len(raw) > 50:
        try:
            return ec.PrivateKey.from_wif(raw)
        except Exception:
            pass
    try:
        return ec.PrivateKey(bytes.fromhex(raw))
    except Exception as e:
        raise SystemExit(
            "Could not read that key. Give either 64 hex characters or a WIF "
            f"string.\n  ({type(e).__name__})")


def digest(message: str) -> bytes:
    """CRYPTTRON-KEY signatures are a plain double-SHA256 over the exact line.

    Deliberately simple and domain-separated by the line's own prefix, so a
    signature made here cannot be replayed as anything else.
    """
    return hashlib.sha256(hashlib.sha256(message.encode()).digest()).digest()


def main() -> int:
    ap = argparse.ArgumentParser(description="Crypttron optional sign-in helper")
    ap.add_argument("--pubkey", metavar="PRIVKEY",
                    help="print the public key for a private key")
    ap.add_argument("--sign", metavar="LINE", help="the line to sign (keep it in quotes)")
    ap.add_argument("--key", metavar="PRIVKEY", help="your private key (hex or WIF)")
    a = ap.parse_args()

    try:
        import embit  # noqa: F401
    except ImportError:
        print("embit is not installed. Run:  pip install embit", file=sys.stderr)
        return 2

    if a.pubkey:
        k = _load_key(a.pubkey)
        print(k.get_public_key().serialize().hex())
        return 0

    if a.sign:
        if not a.key:
            print("--sign also needs --key", file=sys.stderr)
            return 2
        if "|" not in a.sign:
            print("That does not look like a Crypttron line. Copy the whole thing, "
                  "in quotes, including everything after the last |", file=sys.stderr)
            return 2
        k = _load_key(a.key)
        sig = k.sign(digest(a.sign))
        print("public key:", k.get_public_key().serialize().hex())
        print("signature :", sig.serialize().hex())
        print("\nPaste BOTH of those into the site.")
        return 0

    ap.print_help()
    return 1


if __name__ == "__main__":
    sys.exit(main())
