// Tests for the DEBUG build flag as it gates mnemonic generation.
//
// The modules read the __BUILD_DEBUG__ global that esbuild replaces at bundle
// time. Under jest the global is absent, which is exactly the release-build
// case; the debug-build case is exercised by defining the global and
// re-requiring the modules with a fresh registry.

const WORDS_IN_12_WORD_PHRASE = 12;

function loadWallet() {
    const constants = require("../src/shared/constants");
    const wallet = require("../src/shared/wallet");
    const log = require("../src/shared/log");
    return { constants, wallet, log };
}

describe("generateMnemonic in a release build", () => {
    beforeEach(() => {
        jest.resetModules();
        delete globalThis.__BUILD_DEBUG__;
    });

    test("DEBUG defaults to false when the build define is absent", () => {
        const { constants } = loadWallet();
        expect(constants.DEBUG).toBe(false);
    });

    test("returns fresh, valid 12-word phrases that are not the test phrase", () => {
        const { constants, wallet } = loadWallet();

        const first = wallet.generateMnemonic();
        const second = wallet.generateMnemonic();

        expect(first).not.toBe(second);
        for (const phrase of [first, second]) {
            expect(wallet.isValidMnemonic(phrase)).toBe(true);
            expect(phrase.split(" ")).toHaveLength(WORDS_IN_12_WORD_PHRASE);
            expect(phrase).not.toBe(constants.DEBUG_MNEMONIC);
        }
    });

    test("derives a usable HD wallet from the generated phrase", () => {
        const { wallet } = loadWallet();

        const { xpub, firstAddress } = wallet.hdWalletFromMnemonic(
            wallet.generateMnemonic(),
        );

        expect(xpub.startsWith("xpub")).toBe(true);
        expect(firstAddress).toMatch(/^0x[0-9a-fA-F]{40}$/);
    });

    test("the runtime debug toggle cannot re-enable the test phrase", () => {
        const { constants, wallet, log } = loadWallet();

        // What the settings easter-egg toggle does at runtime.
        log.setRuntimeDebug(true);
        expect(log.isDebug()).toBe(true);

        const phrase = wallet.generateMnemonic();
        expect(phrase).not.toBe(constants.DEBUG_MNEMONIC);
        expect(wallet.isValidMnemonic(phrase)).toBe(true);
        expect(phrase).not.toBe(wallet.generateMnemonic());

        log.setRuntimeDebug(false);
    });
});

describe("generateMnemonic in a debug build", () => {
    beforeEach(() => {
        jest.resetModules();
        globalThis.__BUILD_DEBUG__ = true;
    });

    afterEach(() => {
        delete globalThis.__BUILD_DEBUG__;
    });

    test("DEBUG is true and the test phrase is returned", () => {
        const { constants, wallet } = loadWallet();

        expect(constants.DEBUG).toBe(true);
        expect(wallet.generateMnemonic()).toBe(constants.DEBUG_MNEMONIC);
    });

    test("the test phrase is itself a valid 12-word BIP-39 phrase", () => {
        const { constants, wallet } = loadWallet();

        expect(wallet.isValidMnemonic(constants.DEBUG_MNEMONIC)).toBe(true);
        expect(constants.DEBUG_MNEMONIC.split(" ")).toHaveLength(
            WORDS_IN_12_WORD_PHRASE,
        );
    });
});
