#!/usr/bin/env python3

import argparse
import logging
import os
import os.path
import sys

from decimal import Decimal
from solana.publickey import PublicKey
from solana.system_program import TransferParams, transfer
from solana.transaction import Transaction

sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
import mango  # nopep8

parser = argparse.ArgumentParser(description="Sends SOL to a different address.")
mango.ContextBuilder.add_command_line_parameters(parser)
mango.Wallet.add_command_line_parameters(parser)
parser.add_argument(
    "--address",
    type=PublicKey,
    help="Destination address for the SPL token - can be either the actual token address or the address of the owner of the token address",
)
parser.add_argument(
    "--quantity", type=Decimal, required=True, help="quantity of token to send"
)
parser.add_argument(
    "--dry-run",
    action="store_true",
    default=False,
    help="runs as read-only and does not perform any transactions",
)
parser.add_argument(
    "--wait",
    action="store_true",
    default=False,
    help="wait until the transactions are confirmed",
)
args: argparse.Namespace = mango.parse_args(parser)

with mango.ContextBuilder.from_command_line_parameters(args) as context:
    wallet = mango.Wallet.from_command_line_parameters_or_raise(args)

    logging.info(f"Wallet address: {wallet.address}")

    sol_balance = context.client.get_balance(wallet.address)
    mango.output(f"Balance: {sol_balance} SOL")

    # "A lamport has a value of 0.000000001 SOL." from https://docs.solana.com/introduction
    lamports = int(args.quantity * mango.SOL_DECIMAL_DIVISOR)
    source = wallet.address
    destination = args.address

    text_amount = f"{lamports} lamports (SOL @ 9 decimal places)"
    mango.output(f"Sending {text_amount}")
    mango.output(f"    From: {source}")
    mango.output(f"      To: {destination}")

    if args.dry_run:
        mango.output("Skipping actual transfer - dry run.")
    else:
        transaction = Transaction()
        params = TransferParams(
            from_pubkey=source, to_pubkey=destination, lamports=lamports
        )
        transaction.add(transfer(params))

        signatures = [context.client.send_transaction(transaction, wallet.keypair)]

        if args.wait:
            mango.output("Waiting on transaction signatures:")
            mango.output(mango.indent_collection_as_str(signatures, 1))
            results = mango.WebSocketTransactionMonitor.wait_for_all(
                context.client.cluster_ws_url, signatures
            )
            mango.output("Transaction results:")
            mango.output(mango.indent_collection_as_str(results, 1))
        else:
            mango.output("Transaction signatures:")
            mango.output(mango.indent_collection_as_str(signatures, 1))

    updated_balance = context.client.get_balance(wallet.address)
    mango.output(f"{text_amount} sent. Balance now: {updated_balance} SOL")
