import { BigNumber } from "ethers";
import { Implementation__factory } from "../ethers-contracts";
function checkAlphLog(event) {
    if (event.fields.length !== 6) {
        throw Error("invalid event, wormhole message has 6 fields");
    }
}
export function parseSequenceFromLogAlph(event) {
    checkAlphLog(event);
    const field = event.fields[2];
    if (field.type !== 'U256') {
        throw Error("invalid event, expect U256 type, have: " + field.type);
    }
    return field.value;
}
export function parseTargetChainFromLogAlph(event) {
    checkAlphLog(event);
    const field = event.fields[1];
    if (field.type !== 'U256') {
        throw Error("invalid event, expect U256 type, have: " + field.type);
    }
    return parseInt(field.value);
}
export function parseSequenceFromLogEth(receipt, bridgeAddress) {
    // TODO: dangerous!(?)
    const bridgeLog = receipt.logs.filter((l) => {
        return l.address === bridgeAddress;
    })[0];
    const { args: { sequence }, } = Implementation__factory.createInterface().parseLog(bridgeLog);
    return sequence.toString();
}
export function parseTargetChainFromLogEth(receipt, bridgeAddress) {
    const bridgeLog = receipt.logs.filter((l) => {
        return l.address === bridgeAddress;
    })[0];
    const { args: { targetChainId }, } = Implementation__factory.createInterface().parseLog(bridgeLog);
    return parseInt(targetChainId.toString());
}
export function parseSequencesFromLogEth(receipt, bridgeAddress) {
    // TODO: dangerous!(?)
    const bridgeLogs = receipt.logs.filter((l) => {
        return l.address === bridgeAddress;
    });
    return bridgeLogs.map((bridgeLog) => {
        const { args: { sequence }, } = Implementation__factory.createInterface().parseLog(bridgeLog);
        return sequence.toString();
    });
}
export function parseSequenceFromLogTerra(info) {
    // Scan for the Sequence attribute in all the outputs of the transaction.
    // TODO: Make this not horrible.
    let sequence = "";
    const jsonLog = JSON.parse(info.raw_log);
    jsonLog.map((row) => {
        row.events.map((event) => {
            event.attributes.map((attribute) => {
                if (attribute.key === "message.sequence") {
                    sequence = attribute.value;
                }
            });
        });
    });
    return sequence.toString();
}
export function parseSequencesFromLogTerra(info) {
    // Scan for the Sequence attribute in all the outputs of the transaction.
    // TODO: Make this not horrible.
    const sequences = [];
    const jsonLog = JSON.parse(info.raw_log);
    jsonLog.map((row) => {
        row.events.map((event) => {
            event.attributes.map((attribute) => {
                if (attribute.key === "message.sequence") {
                    sequences.push(attribute.value.toString());
                }
            });
        });
    });
    return sequences;
}
const SOLANA_SEQ_LOG = "Program log: Sequence: ";
export function parseSequenceFromLogSolana(info) {
    var _a, _b, _c, _d;
    // TODO: better parsing, safer
    const sequence = (_d = (_c = (_b = (_a = info.meta) === null || _a === void 0 ? void 0 : _a.logMessages) === null || _b === void 0 ? void 0 : _b.filter((msg) => msg.startsWith(SOLANA_SEQ_LOG))) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.replace(SOLANA_SEQ_LOG, "");
    if (!sequence) {
        throw new Error("sequence not found");
    }
    return sequence.toString();
}
export function parseSequencesFromLogSolana(info) {
    var _a, _b;
    // TODO: better parsing, safer
    return (_b = (_a = info.meta) === null || _a === void 0 ? void 0 : _a.logMessages) === null || _b === void 0 ? void 0 : _b.filter((msg) => msg.startsWith(SOLANA_SEQ_LOG)).map((msg) => msg.replace(SOLANA_SEQ_LOG, ""));
}
export function parseSequenceFromLogAlgorand(result) {
    let sequence = "";
    if (result["inner-txns"]) {
        const innerTxns = result["inner-txns"];
        class iTxn {
        }
        innerTxns.forEach((txn) => {
            if (txn.logs) {
                sequence = BigNumber.from(txn.logs[0].slice(0, 8)).toString();
            }
        });
    }
    return sequence;
}
