"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const es6_promisify_1 = require("es6-promisify");
const loggingService_1 = require("./loggingService");
const utils_1 = require("./utils");
/**
 * Methods for querying information about an Avatar.
 * Use it by:
 *
 * let avatarService = new AvatarService(avatarAddress);
 *
 */
class AvatarService {
    constructor(avatarAddress) {
        this.avatarAddress = avatarAddress;
        this.isUController = undefined;
    }
    /**
     * Returns promise of the Avatar Truffle contract wrapper.
     * Returns undefined if not found.
     */
    getAvatar() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.avatar) {
                const Avatar = yield utils_1.Utils.requireContract("Avatar");
                return Avatar.at(this.avatarAddress)
                    .then((avatar) => avatar) // only way to get to catch
                    /* have to handle the catch or promise rejection goes unhandled */
                    .catch((ex) => {
                    loggingService_1.LoggingService.error(`AvatarService: unable to load avatar at ${this.avatarAddress}: ${ex.message}`);
                    return undefined;
                });
            }
        });
    }
    /**
     * Returns promise of the address of the controller
     */
    getControllerAddress() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.controllerAddress) {
                const avatar = yield this.getAvatar();
                if (avatar) {
                    this.controllerAddress = yield avatar.owner();
                }
            }
            return this.controllerAddress;
        });
    }
    /**
     * Returns promise of a Truffle contract wrapper for the controller.  Could be
     * either UController or Controller.  You can know which one
     * by checking the AvatarService instance property `isUController`.
     */
    getController() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.controller) {
                const controllerAddress = yield this.getControllerAddress();
                if (controllerAddress) {
                    /**
                     * TODO:  check for previous and future versions of UController here
                     */
                    const UControllerContract = yield utils_1.Utils.requireContract("UController");
                    const ControllerContract = yield utils_1.Utils.requireContract("Controller");
                    const uControllerAddress = (yield UControllerContract.deployed()).address;
                    this.isUController = uControllerAddress === controllerAddress;
                    this.controller = this.isUController ?
                        yield UControllerContract.at(controllerAddress) :
                        yield ControllerContract.at(controllerAddress);
                }
            }
            return this.controller;
        });
    }
    /**
     * Returns promise of the address of the avatar's native reputation.
     */
    getNativeReputationAddress() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.nativeReputationAddress) {
                const avatar = yield this.getAvatar();
                if (avatar) {
                    this.nativeReputationAddress = yield avatar.nativeReputation();
                }
            }
            return this.nativeReputationAddress;
        });
    }
    /**
     * Returns promise of the avatar's native reputation Truffle contract wrapper.
     */
    getNativeReputation() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.nativeReputation) {
                const reputationAddress = yield this.getNativeReputationAddress();
                if (reputationAddress) {
                    const Reputation = yield utils_1.Utils.requireContract("Reputation");
                    this.nativeReputation = yield Reputation.at(reputationAddress);
                }
            }
            return this.nativeReputation;
        });
    }
    /**
     * Returns promise of the address of the avatar's native token.
     */
    getNativeTokenAddress() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.nativeTokenAddress) {
                const avatar = yield this.getAvatar();
                if (avatar) {
                    this.nativeTokenAddress = yield avatar.nativeToken();
                }
            }
            return this.nativeTokenAddress;
        });
    }
    /**
     * Returns promise of the avatar's native token Truffle contract wrapper.
     * Assumes the token is a `DAOToken`.
     */
    getNativeToken() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!this.nativeToken) {
                const tokenAddress = yield this.getNativeTokenAddress();
                if (tokenAddress) {
                    this.nativeToken = (yield (yield utils_1.Utils.requireContract("DAOToken")).at(tokenAddress));
                }
            }
            return this.nativeToken;
        });
    }
    /**
     * Return a current token balance for this avatar, in Wei.
     * If tokenAddress is not supplied, then uses native token.
     */
    getTokenBalance(tokenAddress) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            let token;
            if (!tokenAddress) {
                token = yield this.getNativeToken();
            }
            else {
                token = yield (yield utils_1.Utils.requireContract("StandardToken")).at(tokenAddress)
                    .then((theToken) => theToken) // only way to get to catch
                    .catch((ex) => {
                    loggingService_1.LoggingService.error(`AvatarService:  unable to load token at ${tokenAddress}: ${ex}`);
                    return undefined;
                });
            }
            return token ? token.balanceOf(this.avatarAddress) : Promise.resolve(undefined);
        });
    }
    /**
     * Return the current ETH balance for this avatar, in Wei.
     */
    getEthBalance() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const web3 = yield utils_1.Utils.getWeb3();
            return es6_promisify_1.promisify((callback) => web3.eth.getBalance(this.avatarAddress, web3.eth.defaultBlock, callback))()
                .then((balance) => {
                return balance;
            });
        });
    }
}
exports.AvatarService = AvatarService;
//# sourceMappingURL=avatarService.js.map