/*
 * Copyright by the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.bitcoinj.examples;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;

import org.bitcoinj.core.*;
import org.bitcoinj.kits.WalletAppKit;
import org.bitcoinj.params.TestNet3Params;
import org.bitcoinj.wallet.Wallet;
import org.bitcoinj.wallet.Wallet.BalanceType;

import java.io.File;

/**
 * The following example shows you how to create a SendRequest to send coins from a wallet to a given address.
 */
public class SendRequest {

    public static void main(String[] args) throws Exception {

        // We use the WalletAppKit that handles all the boilerplate for us. Have a look at the Kit.java example for more details.
        NetworkParameters params = TestNet3Params.get();
        WalletAppKit kit = new WalletAppKit(params, new File("."), "sendrequest-example");
        kit.startAsync();
        kit.awaitRunning();


        // How much coins do we want to send?
        // The Coin class represents a monetary Bitcoin value.
        // We use the parseCoin function to simply get a Coin instance from a simple String.
        Coin value = Coin.parseCoin("0.09");

        // To which address you want to send the coins?
        // The Address class represents a Bitcoin address.
        LegacyAddress to = LegacyAddress.fromBase58(params, "mupBAFeT63hXfeeT4rnAUcpKHDkz1n4fdw");
        System.out.println("Send money to: " + to.toString());

        // There are different ways to create and publish a SendRequest. This is probably the easiest one.
        // Have a look at the code of the SendRequest class to see what's happening and what other options you have: https://bitcoinj.github.io/javadoc/0.11/com/google/bitcoin/core/Wallet.SendRequest.html
        // 
        // Please note that this might raise a InsufficientMoneyException if your wallet has not enough coins to spend.
        // When using the testnet you can use a faucet to get testnet coins.
        // In this example we catch the InsufficientMoneyException and register a BalanceFuture callback that runs once the wallet has enough balance.
        try {
            Wallet.SendResult result = kit.wallet().sendCoins(kit.peerGroup(), to, value);
            System.out.println("coins sent. transaction hash: " + result.tx.getTxId());
            // you can use a block explorer like https://www.biteasy.com/ to inspect the transaction with the printed transaction hash. 
        } catch (InsufficientMoneyException e) {
            System.out.println("Not enough coins in your wallet. Missing " + e.missing.getValue() + " satoshis are missing (including fees)");
            System.out.println("Send money to: " + kit.wallet().currentReceiveAddress().toString());

            // Bitcoinj allows you to define a BalanceFuture to execute a callback once your wallet has a certain balance.
            // Here we wait until the we have enough balance and display a notice.
            // Bitcoinj is using the ListenableFutures of the Guava library. Have a look here for more information: https://github.com/google/guava/wiki/ListenableFutureExplained
            ListenableFuture<Coin> balanceFuture = kit.wallet().getBalanceFuture(value, BalanceType.AVAILABLE);
            FutureCallback<Coin> callback = new FutureCallback<Coin>() {
                @Override
                public void onSuccess(Coin balance) {
                    System.out.println("coins arrived and the wallet now has enough balance");
                }

                @Override
                public void onFailure(Throwable t) {
                    System.out.println("something went wrong");
                }
            };
            Futures.addCallback(balanceFuture, callback, MoreExecutors.directExecutor());
        }

        // shutting down 
        //kit.stopAsync();
        //kit.awaitTerminated();
    }
}

@@ -643,231 +643,8 @@
 s;%0A%0A
-import com.google.common.util.concurrent.FutureCallback;%0Aimport com.google.common.util.concurrent.Futures;%0Aimport com.google.common.util.concurrent.ListenableFuture;%0Aimport com.google.common.util.concurrent.MoreExecutors;%0A%0A
 impo
@@ -667,16 +667,16 @@
 core.*;%0A
+
 import o
@@ -832,16 +832,16 @@
 eType;%0A%0A
-
 import j
@@ -852,16 +852,63 @@
 io.File;
+%0Aimport java.util.concurrent.CompletableFuture;
 %0A%0A/**%0A *
@@ -3424,20 +3424,16 @@
 t until 
-the 
 we have 
@@ -3485,436 +3485,209 @@
     
-// Bitcoinj is using the ListenableFutures of the Guava library. Have a look here for more information: https://github.com/google/guava/wiki/ListenableFutureExplained%0A            ListenableFuture%3CCoin%3E balanceFuture = kit.wallet().getBalanceFuture(value, BalanceType.AVAILABLE);%0A            FutureCallback%3CCoin%3E callback = new FutureCallback%3CCoin%3E() %7B%0A                @Override%0A                public void onSuccess(Coin balance
+CompletableFuture%3CCoin%3E balanceFuture = kit.wallet().getBalanceFuture(value, BalanceType.AVAILABLE);%0A            balanceFuture.whenComplete((balance, throwable) -%3E %7B%0A                if (balance != null
 ) %7B%0A
@@ -3802,86 +3802,13 @@
    %7D
-%0A%0A                @Override%0A                public void onFailure(Throwable t)
+ else
  %7B%0A 
@@ -3905,97 +3905,8 @@
    %7D
-;%0A            Futures.addCallback(balanceFuture, callback, MoreExecutors.directExecutor()
 );%0A 

migrate from ListenableFuture to CompletableFuture