"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.WriteableToken = exports.ReadOnlyToken = void 0;

var _ethers = require("ethers");

var _token = require("./util/token");

var _registry = require("./registry");

var _types = require("./types");

var _provider = require("./provider");

var _owner = require("./owner");

var _logger = require("./util/logger");

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

/**
 * Class Token to read info from ERC721 contract.
 */
class ReadOnlyToken {
  constructor({
    document,
    web3Provider = (0, _provider.getWeb3Provider)(),
    network = _types.EthereumNetwork.Ropsten // Default to Ropsten since we currently only operate on Ropsten

  }) {
    _defineProperty(this, "document", void 0);

    _defineProperty(this, "web3Provider", void 0);

    _defineProperty(this, "tokenRegistry", void 0);

    this.document = document;
    this.web3Provider = web3Provider || (0, _ethers.getDefaultProvider)(network);
    this.tokenRegistry = new _registry.TokenRegistry({
      contractAddress: (0, _token.getIssuerAddress)(document),
      web3Provider: this.web3Provider
    });
  }

  getOwner() {
    var _this = this;

    return _asyncToGenerator(function* () {
      const ownerAddress = yield _this.tokenRegistry.ownerOf(_this.document);
      return (0, _owner.createOwner)({
        address: ownerAddress,
        web3Provider: _this.web3Provider
      });
    })();
  }

}

exports.ReadOnlyToken = ReadOnlyToken;

class WriteableToken extends ReadOnlyToken {
  constructor({
    document,
    web3Provider = (0, _provider.getWeb3Provider)(),
    wallet = (0, _provider.getWallet)(),
    network = _types.EthereumNetwork.Ropsten // Default to Ropsten since we currently only operate on Ropsten

  }) {
    super({
      document,
      web3Provider,
      network
    });

    _defineProperty(this, "wallet", void 0);

    if (!wallet) {
      throw new Error("WriteableToken requires a wallet to be supplied at initialisation");
    }

    this.wallet = wallet;
    this.tokenRegistry = new _registry.TokenRegistry({
      contractAddress: (0, _token.getIssuerAddress)(this.document),
      web3Provider: this.web3Provider,
      wallet
    });
  }

  getOwner() {
    var _this2 = this;

    return _asyncToGenerator(function* () {
      const ownerAddress = yield _this2.tokenRegistry.ownerOf(_this2.document);
      return (0, _owner.createOwner)({
        address: ownerAddress,
        web3Provider: _this2.web3Provider,
        wallet: _this2.wallet
      });
    })();
  }

  transferOwnership(to) {
    var _this3 = this;

    return _asyncToGenerator(function* () {
      return _this3.tokenRegistry.transferTo(_this3.document, to);
    })();
  }

  mint(to) {
    var _this4 = this;

    return _asyncToGenerator(function* () {
      return _this4.tokenRegistry.mint(_this4.document, to);
    })();
  }

  transferToNewEscrow(beneficiary, holder) {
    var _this5 = this;

    return _asyncToGenerator(function* () {
      (0, _logger.trace)(`Deploying escrow contract before transferring`);
      const escrowInstance = yield _owner.WriteableTitleEscrowOwner.deployEscrowContract({
        registryAddress: _this5.tokenRegistry.address,
        beneficiaryAddress: beneficiary,
        holderAddress: holder,
        wallet: _this5.wallet,
        web3Provider: _this5.web3Provider
      });
      (0, _logger.trace)(`Escrow contract deployed to ${escrowInstance.address}, transferring to it now.`);
      return _this5.transferOwnership(escrowInstance.address);
    })();
  }

  mintToEscrow(beneficiary, holder) {
    var _this6 = this;

    return _asyncToGenerator(function* () {
      (0, _logger.trace)(`Deploying escrow contract before minting`);
      const escrowInstance = yield _owner.WriteableTitleEscrowOwner.deployEscrowContract({
        registryAddress: _this6.tokenRegistry.address,
        beneficiaryAddress: beneficiary,
        holderAddress: holder,
        wallet: _this6.wallet,
        web3Provider: _this6.web3Provider
      });
      (0, _logger.trace)(`Escrow contract deployed to ${escrowInstance.address}, minting to it now.`);
      return _this6.mint(escrowInstance.address);
    })();
  }

  surrender() {
    var _this7 = this;

    return _asyncToGenerator(function* () {
      const tokenOwner = yield _this7.getOwner();

      if (tokenOwner instanceof _owner.WriteableTitleEscrowOwner) {
        return tokenOwner.transferTo(_this7.tokenRegistry.address);
      }

      return _this7.tokenRegistry.transferTo(_this7.document, _this7.tokenRegistry.address);
    })();
  }

}

exports.WriteableToken = WriteableToken;