package com.samourai.wallet.segwit.bech32;

import com.samourai.wallet.SamouraiWallet;

import org.apache.commons.lang3.tuple.Pair;
import org.bouncycastle.util.encoders.Hex;

import org.bitcoinj.crypto.MnemonicException;
import org.bitcoinj.params.TestNet3Params;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.TransactionOutput;

public class Bech32Util {

    private static Bech32Util instance = null;

    private Bech32Util() { ; }

    public static Bech32Util getInstance() {

        if(instance == null) {
            instance = new Bech32Util();
        }

        return instance;
    }

    public boolean isBech32Script(String script) {
        return isP2WPKHScript(script) || isP2WSHScript(script);
    }

    public boolean isP2WPKHScript(String script) {
        return script.startsWith("0014");
    }

    public boolean isP2WSHScript(String script) {
        return script.startsWith("0020");
    }

    public String getAddressFromScript(String script) throws Exception    {

        String hrp = null;
        if(SamouraiWallet.getInstance().getCurrentNetworkParams() instanceof TestNet3Params)    {
            hrp = "tb";
        }
        else    {
            hrp = "bc";
        }

        return Bech32Segwit.encode(hrp, (byte)0x00, Hex.decode(script.substring(4).getBytes()));
    }

    public TransactionOutput getTransactionOutput(String address, long value) throws Exception    {

        TransactionOutput output = null;

        if(address.toLowerCase().startsWith("tb") || address.toLowerCase().startsWith("bc"))   {

            byte[] scriptPubKey = null;

            try {
                Pair<Byte, byte[]> pair = Bech32Segwit.decode(SamouraiWallet.getInstance().isTestNet() ? "tb" : "bc", address);
                scriptPubKey = Bech32Segwit.getScriptPubkey(pair.getLeft(), pair.getRight());
            }
            catch(Exception e) {
                return null;
            }
            output = new TransactionOutput(SamouraiWallet.getInstance().getCurrentNetworkParams(), null, Coin.valueOf(value), scriptPubKey);
        }

        return output;
    }

}

@@ -815,16 +815,55 @@
 (%220014%22)
+ && script.length() == (20 * 2 + 2 * 2)
 ;%0A    %7D%0A
@@ -953,24 +953,63 @@
 (%220020%22)
+ && script.length() == (32 * 2 + 2 * 2)
 ;%0A    %7D%0A
 %0A    pub
@@ -992,32 +992,34 @@
 + 2 * 2);%0A    %7D%0A
+/*
 %0A    public Stri
@@ -1387,32 +1387,34 @@
 ytes()));%0A    %7D%0A
+*/
 %0A    public Tran

check script lengths