// Wallets already in stored state whose key cannot be used, and the copy that
// explains them.
//
// Refusing a non-master extended private key at import time does nothing for a
// wallet imported before that refusal existed. Such a wallet is detected here,
// at wallet-list render time, so the user meets the explanation on the list
// screen rather than an exception on the send screen. Nothing here modifies or
// removes a wallet: the record is the user's data.

const { parseExtendedKey } = require("./wallet");

const NON_MASTER_XPRV = "non-master-xprv";

// An "xprv" wallet stores the neutered BIP-44 Ethereum node, four levels below
// the key that was imported: the current import path derives the absolute
// m/44'/60'/0'/0 from a depth-0 key, and the pre-#210 path derived the same
// four levels as a relative path beneath whatever depth it was given. A master
// import therefore stores a depth-4 xpub and a depth-d import stores depth
// d + 4, which makes the stored xpub an exact read on the imported key's
// depth — and it is readable without the password, unlike the key itself.
const BIP44_ETH_XPUB_DEPTH = 4;

const DEFECTS = {
    [NON_MASTER_XPRV]: {
        id: NON_MASTER_XPRV,
        heading: "This wallet's addresses were derived incorrectly.",
        paragraphs: [
            "This wallet was imported from an extended private key that is " +
                "not a master key. An earlier version applied the Ethereum " +
                "derivation path beneath that key instead of from a master " +
                "key, so the addresses listed here are not the ones that key " +
                "produces under the standard path.",
            "Signing and sending are disabled for this wallet. The addresses " +
                "do descend from the extended private key you imported, so " +
                "anything they hold is still reachable by software that " +
                "repeats the same non-standard derivation. Check them in a " +
                "block explorer before deciding what to do.",
            "To see the addresses this key produces under the standard path, " +
                "import the master extended private key, or the recovery " +
                "phrase it came from, as a new wallet. Nothing here has been " +
                "changed or removed, and this wallet stays until you delete " +
                "it yourself.",
        ],
        // One sentence for the places that have room for one: the flash on a
        // blocked Send, the inline error on the approval screens.
        shortMessage:
            "This wallet cannot sign, because it was imported from an " +
            "extended private key that is not a master key. The wallet list " +
            "explains what happened.",
    },
};

// The defect record for a wallet, or null if there is nothing wrong with it
// that this module can see. Read-only.
//
// A wallet whose xpub will not parse gets null rather than a defect: there is
// no basis in that case to tell the user their key was not a master key, and a
// wrong explanation is worse than none.
function walletDefect(walletData) {
    if (!walletData || walletData.type !== "xprv") return null;
    const node = parseExtendedKey(walletData.xpub);
    if (!node) return null;
    if (node.depth === BIP44_ETH_XPUB_DEPTH) return null;
    return DEFECTS[NON_MASTER_XPRV];
}

// The notice block for the wallet list, or "" for a wallet with no defect.
// The copy is fixed text from this module, so it needs no escaping.
function walletDefectHtml(walletData) {
    const defect = walletDefect(walletData);
    if (!defect) return "";
    let html =
        '<div class="border border-red-500 border-dashed p-2 my-1 text-xs text-red-500">';
    html += `<div class="font-bold mb-1">${defect.heading}</div>`;
    for (const p of defect.paragraphs) {
        html += `<p class="mb-1">${p}</p>`;
    }
    html += "</div>";
    return html;
}

module.exports = {
    NON_MASTER_XPRV,
    walletDefect,
    walletDefectHtml,
};
