import { Dcomm, BinTools, BN, Buffer } from "dcomm/dist"
import {
  AuthorityVMAPI,
  KeyChain as AuthorityVMKeyChain
} from "dcomm/dist/apis/authorityvm"
import {
  EVMAPI,
  KeyChain as EVMKeyChain,
  UnsignedTx,
  Tx,
  EVMInput,
  ExportTx,
  SECPTransferOutput,
  TransferableOutput
} from "dcomm/dist/apis/evm"
import {
  PrivateKeyPrefix,
  DefaultLocalGenesisPrivateKey,
  Defaults,
  ONEDCM
} from "dcomm/dist/utils"
const Web3 = require("web3")

const ip: string = "localhost"
const port: number = 9650
const protocol: string = "http"
const networkID: number = 1337
const dcomm: Dcomm = new Dcomm(ip, port, protocol, networkID)
const athchain: AuthorityVMAPI = dcomm.ATHChain()
const actchain: EVMAPI = dcomm.ACTChain()
const bintools: BinTools = BinTools.getInstance()
const pKeychain: AuthorityVMKeyChain = athchain.keyChain()
let privKey: string = `${PrivateKeyPrefix}${DefaultLocalGenesisPrivateKey}`
// AST-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p

// let privKey: string = "PrivateKey-2PvNEohp3sNL41g4XcCBym5hpeT1szSTZXxL7VGS28eoGvq3k7"
const cKeychain: EVMKeyChain = actchain.keyChain()
cKeychain.importKey(privKey)

privKey = "PrivateKey-24gdABgapjnsJfnYkfev6YPyQhTaCU72T9bavtDNTYivBLp2eW"
// ATH-custom1u6eth2fg33ye63mnyu5jswtj326jaypvhyar45
pKeychain.importKey(privKey)

// privKey = "PrivateKey-R6e8f5QSa89DjpvL9asNdhdJ4u8VqzMJStPV8VVdDmLgPd8a4"
// AST-custom15s7p7mkdev0uajrd0pzxh88kr8ryccztnlmzvj

privKey = "PrivateKey-rKsiN3X4NSJcPpWxMSh7WcuY653NGQ7tfADgQwDZ9yyUPPDG9"
// ATH-custom1jwwk62ktygl0w29rsq2hq55amamhpvx82kfnte
pKeychain.importKey(privKey)
const pAddresses: Buffer[] = athchain.keyChain().getAddresses()
const cAddresses: Buffer[] = actchain.keyChain().getAddresses()
const athChainId: string = Defaults.network[networkID].ATH.blockchainID
const athChainIdBuf: Buffer = bintools.cb58Decode(athChainId)
const actChainId: string = Defaults.network[networkID].ACT.blockchainID
const actChainIdBuf: Buffer = bintools.cb58Decode(actChainId)
const dcmAssetID: string = Defaults.network[networkID].AST.dcmAssetID
const dcmAssetIDBuf: Buffer = bintools.cb58Decode(dcmAssetID)
const cHexAddress: string = "0xeA6B543A9E625C04745EcA3D7a74D74B733b8C15"
const evmInputs: EVMInput[] = []
const exportedOuts: TransferableOutput[] = []
const path: string = "/ext/bc/ACT/rpc"
const web3 = new Web3(`${protocol}://${ip}:${port}${path}`)
const threshold: number = 2

const main = async (): Promise<any> => {
  let balance: BN = await web3.eth.getBalance(cHexAddress)
  balance = new BN(balance.toString().substring(0, 17))
  const fee: BN = actchain.getDefaultTxFee()
  const txcount = await web3.eth.getTransactionCount(cHexAddress)
  const nonce: number = txcount
  const locktime: BN = new BN(0)

  const evmInput: EVMInput = new EVMInput(
    cHexAddress,
    ONEDCM,
    dcmAssetID,
    nonce
  )
  evmInput.addSignatureIdx(0, cAddresses[0])
  evmInputs.push(evmInput)

  const secpTransferOutput: SECPTransferOutput = new SECPTransferOutput(
    ONEDCM.sub(fee.mul(new BN(2))),
    pAddresses,
    locktime,
    threshold
  )
  const transferableOutput: TransferableOutput = new TransferableOutput(
    dcmAssetIDBuf,
    secpTransferOutput
  )
  exportedOuts.push(transferableOutput)

  const exportTx: ExportTx = new ExportTx(
    networkID,
    actChainIdBuf,
    athChainIdBuf,
    evmInputs,
    exportedOuts
  )

  const unsignedTx: UnsignedTx = new UnsignedTx(exportTx)
  const tx: Tx = unsignedTx.sign(cKeychain)
  const txid: string = await actchain.issueTx(tx)
  console.log(`Success! TXID: ${txid}`)
}

main()
