/*
 * 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.drausin.bitflow.blockchain;

import static org.junit.Assert.assertTrue;

import org.bitcoinj.core.Sha256Hash;
import org.drausin.bitflow.blockchain.api.objects.BlockHeader;
import org.drausin.bitflow.blockchain.api.objects.BlockchainInfo;
import org.drausin.bitflow.integration.AbstractIntegrationTest;
import org.junit.Test;

public final class BlockchainServerIntegrationTests extends AbstractIntegrationTest {

    @Test
    public void testGetBlockchainInfo() {

        // ideally we would be able to hit the BitcoinNode endpoint directly, but the rpcallowip configuration parameter
        // means that we can only hit that endpoint from within the docker-compose 'bitflow' network, so for now the
        // commented portions won't work :/

        /*
        // get from the BitcoinNode endpoint
        BitcoinNodeRequest blockchainInfoRequest = BitcoinNodeRequestFactory.createBlockchainInfoRequest();
        BlockchainInfoResponse bitcoinNodeBlockchainInfoResponse = getBitcoinNode().getBlockchainInfo(
                blockchainInfoRequest);
        bitcoinNodeBlockchainInfoResponse.validateResult();
        BlockchainInfo bitcoinNodeBlockchainInfo = bitcoinNodeBlockchainInfoResponse.getResult().get();
        */

        // get from the Blockchain endpoint
        BlockchainInfo blockchainBlockchainInfo = getBlockchainService().getBlockchainInfo("dummy header");
        assertTrue(blockchainBlockchainInfo.getNumBlocks() > 0);

        /*
        // this stuff should be the same
        assertEquals(bitcoinNodeBlockchainInfo.getChain(), blockchainBlockchainInfo.getChain());
        assertEquals(bitcoinNodeBlockchainInfo.getPruned(), blockchainBlockchainInfo.getPruned());

        // the second Blockchain end point call should have a block greater than or equal to the first
        assertTrue(bitcoinNodeBlockchainInfo.getNumBlocks() <= blockchainBlockchainInfo.getNumBlocks());
        assertTrue(bitcoinNodeBlockchainInfo.getNumHeaders() <= blockchainBlockchainInfo.getNumHeaders());
        assertTrue(bitcoinNodeBlockchainInfo.getVerificationProgress()
                <= bitcoinNodeBlockchainInfo.getVerificationProgress());
        assertTrue(bitcoinNodeBlockchainInfo.getPruneHeight() <= blockchainBlockchainInfo.getPruneHeight());
        */
    }

    @Test
    public void testGetBlockHeaderUnpruned() {

        BlockchainInfo blockchainInfo = getBlockchainService().getBlockchainInfo("dummy header");
        BlockHeader blockHeader = getBlockchainService().getBlockHeader("dummer header",
                blockchainInfo.getBestBlockHash());

        assertTrue(blockHeader.getTransactionIds().size() > 0);

    }

    @Test(expected = RuntimeException.class)
    public void testGetBlockHeaderPruned() {

        // make request for block that's probably not available, which should result in a RuntimeException
        Sha256Hash headerHash = Sha256Hash.wrap("000000000fe549a89848c76070d4132872cfb6efe5315d01d7ef77e4900f2d39");
        getBlockchainService().getBlockHeader("dummer header", headerHash);
    }
}

@@ -638,14 +638,82 @@
 sert
-True;%0A
+Equals;%0Aimport static org.junit.Assert.assertTrue;%0A%0Aimport java.util.List;
 %0Aimp
@@ -1046,24 +1046,90 @@
 tionTest %7B%0A%0A
+    private static final String authHeader = %22dummy authHeader%22;%0A%0A
     @Test%0A  
@@ -2034,39 +2034,32 @@
  = getBlockchain
-Service
 ().getBlockchain
@@ -2059,38 +2059,34 @@
 ckchainInfo(
-%22dummy h
+authH
 eader
-%22
 );%0A        a
@@ -3080,39 +3080,32 @@
  = getBlockchain
-Service
 ().getBlockchain
@@ -3113,22 +3113,18 @@
 nfo(
-%22dummy h
+authH
 eader
-%22
 );%0A 
@@ -3161,39 +3161,32 @@
  = getBlockchain
-Service
 ().getBlockHeade
@@ -3191,40 +3191,19 @@
 der(
-%22dummer header%22,%0A               
+authHeader,
  blo
@@ -3648,62 +3648,705 @@
 hain
-Service().getBlockHeader(%22dummer header%22, headerHash);
+().getBlockHeader(authHeader, headerHash);%0A    %7D%0A%0A    @Test%0A    public void testGetBlockHeaderHeightSubchain() %7B%0A%0A        BlockchainInfo blockchainInfo = getBlockchain().getBlockchainInfo(authHeader);%0A        long toBlockHeight = blockchainInfo.getNumBlocks();%0A        long fromBlockHeight = toBlockHeight - 5;%0A        List%3CBlockHeader%3E subchain = getBlockchain().getBlockHeaderHeightSubchain(authHeader, fromBlockHeight,%0A                toBlockHeight);%0A%0A        assertEquals(toBlockHeight - fromBlockHeight + 1, subchain.size());%0A        for (int c = 1; c %3C subchain.size(); c++) %7B%0A            assertEquals(subchain.get(c - 1).getNextBlockHash().get(), subchain.get(c).getHeaderHash());%0A        %7D
 %0A   

add testGetBlockHeaderHeightSubchain() integration test