const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);
const {web3, waitForConnectionAsync, ACCOUNT, timeout} = require('./helper');

async function deployContract(name) {
  const contractBin = await readFile(`../build/${name}.bin`);
  const contractAbi = require(`../src/assets/contract/${name}.json`);
  const deployContract = new web3.eth.Contract(contractAbi);

  console.log(`deploy ${name}...`);

  return await deployContract.deploy({
    data: '0x' + contractBin,
  })
    .send({
      from: ACCOUNT,
      gas: 1500000,
      gasPrice: '100000000000'
    })
    .on('error', console.error)
    .on('transactionHash', function (transactionHash) {
      console.log(`transaction hash: `, transactionHash);
    })
    .on('receipt', function (receipt) {
      console.log('the new contract address: ', receipt.contractAddress)
    })
    .catch(e => console.error(`failed to receipt  new contract address:`, e))
    // .on('confirmation', function (confirmationNumber, receipt) {
    //   console.log('confirmation', confirmationNumber, receipt)
    // })
    .then(function (newContractInstance) {
      console.log('new contract', newContractInstance.options.address); // instance with the new contract address
      return newContractInstance;
    });
}

async function unlockAccount() {
  await web3.eth.personal.unlockAccount(ACCOUNT, '', null);
}

async function testContract(contrat) {
  // todo
}

async function copyContracts(c) {
  return await new Promise((resolve, reject) =>
    fs.copyFile(`../build/${c}.abi`, `../src/assets/contract/${c}.json`, err => {
      if (err) {
        reject(err);
      }
      resolve();
    }));
}


async function writeConfig(infos) {
  await writeFile('../src/assets/contract/deployment.json', JSON.stringify(infos));
}

async function run() {
  await waitForConnectionAsync();
  const contracts = ['RandomGuess', 'HelloWorld', 'Signaling'];
  const contractInofs = {};
  for (let c of contracts) {
    await copyContracts(c);
    await unlockAccount();
    const contract = await deployContract(c);
    contractInofs[c] = contract.options.address;
    await testContract(contract);
    // if (c !== contracts[contracts.length - 1]) {
    //   // wait between contracts -> throws error without
    //   console.log('wait to start with deployment...');
    //   await timeout(5000);
    // }
  }
  await writeConfig({contracts: contractInofs});
  process.exit();
}

try {
  run();
} catch (e) {
  process.exit(-1);
}

