use bft_json_crdt::json_crdt::SignedOp;
use serde_json::{json, Value};
use std::path::PathBuf;

pub(crate) const BITCOIN_KEY_FILE: &str = "bitcoin_keys.pem";
pub(crate) const BFT_CRDT_KEY_FILE: &str = "keys.pem";
pub(crate) const CONFIG_FILE: &str = "config.toml";

/// Returns the path to the key file and config for this host OS.
pub(crate) fn side_paths(prefix: PathBuf) -> (PathBuf, PathBuf, PathBuf) {
    let mut bft_crdt_key_path = prefix.clone();
    bft_crdt_key_path.push(BFT_CRDT_KEY_FILE);

    let mut bitcoin_key_path = prefix.clone();
    bitcoin_key_path.push(BITCOIN_KEY_FILE);

    let mut config_path = prefix.clone();
    config_path.push(CONFIG_FILE);

    (bft_crdt_key_path, bitcoin_key_path, config_path)
}

/// Returns the path to the home directory for this host OS and the given node name
pub(crate) fn home(name: &String) -> std::path::PathBuf {
    let mut path = dirs::home_dir().unwrap();
    path.push(".side");
    path.push(name);
    path
}

/// Generate a fake transaction with customizable from_pubkey String
pub fn fake_generic_transaction_json(from: String) -> Value {
    json!({
        "from": from,
        "to": "Bob",
        "amount": 1
    })
}

/// Generate a Bitcoin transaction from this node's bitcoin_keys
// pub fn fake_bitcoin_transaction(key_pair: Keypair) -> bitcoin::Transaction {
//     let from = key_pair.public_key().to_string();
//     let to = "Bob";
//     let amount = 1;
//     let lock_time = absolute::LockTime::from_height(0).expect("couldn't format btc lock time");
//     let input = TxIn {
//         previous_output: todo!(),
//         script_sig: todo!(),
//         sequence: todo!(),
//         witness: todo!(),
//     };
//     let output = TxOut {
//         value: todo!(),
//         script_pubkey: todo!(),
//     };
//     let tx = bitcoin::Transaction {
//         version: Version(1),
//         lock_time,
//         input: vec![input],
//         output: vec![output],
//     };
//     tx
// }

pub fn shappy(op: SignedOp) -> String {
    let b = serde_json::to_string(&op).unwrap().into_bytes();
    sha256::digest(b).to_string()
}

pub fn shassy(text: String) -> String {
    let b = text.into_bytes();
    sha256::digest(b).to_string()
}
