#!/usr/bin/env python3
"""
Bitcoin Wallet Generation Script

This script generates a Bitcoin wallet and stores it in a KeePassXC database file (KDBX format).
The wallet includes a BIP-0039 mnemonic seed phrase, Bitcoin address, and a QR code representation
of the seed phrase. The database file is password protected to ensure the security of the wallet.

Usage: ./generate_btc_wallet.py
"""

import gc
from getpass import getpass
from mnemonic import Mnemonic
from bitcoinlib.keys import HDKey
from pykeepass import create_database

MNEMONIC_STRENGTH=256
SUBKEY_PATH="m/0/0"

# Generate a BIP-0039 mnemonic seed phrase
mnemonic = Mnemonic("english")
SEED_PHRASE = mnemonic.generate(strength=MNEMONIC_STRENGTH)

# Derive the HDKey from the seed phrase
hd_key = HDKey.from_passphrase(SEED_PHRASE)

# Derive the Bitcoin address from the HDKey
child_key = hd_key.subkey_for_path(SUBKEY_PATH)
address = child_key.address()

# Prompt for custom name for the wallet
wallet_name = input(
    "Whould you like to name this wallet? (empty for using the address as name): "
).strip()

# Create the database filename with the wallet number
if wallet_name == "":
    wallet_name = address
else:
    wallet_name = wallet_name[:100].strip()

db_filename = f"{wallet_name}.kdbx"

# Prompt the user for the passphrase
passphrase = getpass("Enter passphrase for the KeePassXC database: ")

try:
    # Create a KeePassXC database file
    db = create_database(db_filename, password=passphrase)

    # Create an entrys in the root group
    address_and_path_entry = db.add_entry(db.root_group, wallet_name, username=address, password=SUBKEY_PATH)
    seed_phrase_entry = db.add_entry(db.root_group, "Bitcoin Master Seed", username="put me in safe", password=SEED_PHRASE)

    # Save the database
    db.save()
except Exception as e:
    print("Error while creating keepassxc database. Disk full? Readonly?")
finally:
    del SEED_PHRASE, address, hd_key, passphrase, mnemonic
    gc.collect()

print("---")
print("Bitcoin address was successfully created. You can find at: " + db_filename)
print("---")