content: /*
   * Copyright 2019 ACINQ SAS
   *
   * 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 fr.acinq.eclair.blockchain.electrum;
  
  import android.util.Log;
  
  import org.junit.AfterClass;
  import org.junit.Assert;
  import org.junit.BeforeClass;
  import org.junit.Test;
  
  import java.net.InetSocketAddress;
  
  import akka.actor.ActorRef;
  import akka.actor.ActorSystem;
  import akka.actor.Props;
  import akka.testkit.JavaTestKit;
  import fr.acinq.bitcoin.ByteVector32;
  import fr.acinq.bitcoin.Crypto;
  import fr.acinq.bitcoin.Transaction;
  import scala.Option;
  
  public class ElectrumClientTest {
  
    static ActorSystem system;
  
    @BeforeClass
    public static void setup() {
      system = ActorSystem.create();
    }
  
    @AfterClass
    public static void teardown() {
      JavaTestKit.shutdownActorSystem(system);
      system = null;
    }
  
    @Test
    public void basicTest() {
      new JavaTestKit(system) {{
        final InetSocketAddress address = new InetSocketAddress("testnetnode.arihanc.com", 51001);
        // TODO: how to properly instantiate SSL.OFF from java ?
        final Props props = Props.create(ElectrumClient.class, address, system.dispatcher());
        final ActorRef subject = system.actorOf(props);
  
        new Within(duration("3 seconds")) {
          protected void run() {
            subject.tell(new ElectrumClient.AddStatusListener(getRef()), getRef());
            expectMsgClass(duration("1 second"), ElectrumClient.ElectrumReady.class);
          }
        };
  
        new Within(duration("3 seconds")) {
          protected void run() {
            subject.tell(new ElectrumClient.GetTransaction(ByteVector32.fromValidHex("c5efb5cbd35a44ba956b18100be0a91c9c33af4c7f31be20e33741d95f04e202"), Option.empty()), getRef());
            ElectrumClient.GetTransactionResponse response = expectMsgClass(duration("1 second"), ElectrumClient.GetTransactionResponse.class);
            Assert.assertEquals(response.tx().txid().toString(), "c5efb5cbd35a44ba956b18100be0a91c9c33af4c7f31be20e33741d95f04e202");
          }
        };
  
        new Within(duration("3 seconds")) {
          protected void run() {
            subject.tell(new ElectrumClient.GetMerkle(ByteVector32.fromValidHex("c5efb5cbd35a44ba956b18100be0a91c9c33af4c7f31be20e33741d95f04e202"), 1210223, Option.empty()), getRef());
            ElectrumClient.GetMerkleResponse response = expectMsgClass(duration("1 second"), ElectrumClient.GetMerkleResponse.class);
            Assert.assertEquals(response.txid(), ByteVector32.fromValidHex("c5efb5cbd35a44ba956b18100be0a91c9c33af4c7f31be20e33741d95f04e202"));
            Assert.assertEquals(response.block_height(), 1210223L);
            Assert.assertEquals(response.pos(), 28);
          }
        };
  
        new Within(duration("3 seconds")) {
          protected void run() {
            subject.tell(new ElectrumClient.HeaderSubscription(getRef()), getRef());
            ElectrumClient.HeaderSubscriptionResponse response = expectMsgClass(duration("1 second"), ElectrumClient.HeaderSubscriptionResponse.class);
            Log.i("received header", response.header().toString());
          }
        };
  
        new Within(duration("3 seconds")) {
          protected void run() {
            Transaction referenceTx = (Transaction) Transaction.read("0200000003947e307df3ab452d23f02b5a65f4ada1804ee733e168e6197b0bd6cc79932b6c010000006a473044022069346ec6526454a481690a3664609f9e8032c34553015cfa2e9b25ebb420a33002206998f21a2aa771ad92a0c1083f4181a3acdb0d42ca51d01be1309da2ffb9cecf012102b4568cc6ee751f6d39f4a908b1fcffdb878f5f784a26a48c0acb0acff9d88e3bfeffffff966d9d969cd5f95bfd53003a35fcc1a50f4fb51f211596e6472583fdc5d38470000000006b4830450221009c9757515009c5709b5b678d678185202b817ef9a69ffb954144615ab11762210220732216384da4bf79340e9c46d0effba6ba92982cca998adfc3f354cec7715f800121035f7c3e077108035026f4ebd5d6ca696ef088d4f34d45d94eab4c41202ec74f9bfefffffff8d5062f5b04455c6cfa7e3f250e5a4fb44308ba2b86baf77f9ad0d782f57071010000006a47304402207f9f7dd91fe537a26d5554105977e3949a5c8c4ef53a6a3bff6da2d36eff928f02202b9427bef487a1825fd0c3c6851d17d5f19e6d73dfee22bf06db591929a2044d012102b4568cc6ee751f6d39f4a908b1fcffdb878f5f784a26a48c0acb0acff9d88e3bfeffffff02809698000000000017a914c82753548fdf4be1c3c7b14872c90b5198e67eaa876e642500000000001976a914e2365ec29471b3e271388b22eadf0e7f54d307a788ac6f771200");
            ByteVector32 hash = Crypto.sha256().apply(referenceTx.txOut().apply(0).publicKeyScript()).reverse();
            subject.tell(new ElectrumClient.ScriptHashSubscription(hash, getRef()), getRef());
            ElectrumClient.ScriptHashSubscriptionResponse response = expectMsgClass(duration("1 second"), ElectrumClient.ScriptHashSubscriptionResponse.class);
            System.out.println("received scripthash status " + response.status());
          }
        };
      }};
    }
  }
  
  