"use strict";
var ChromeClient = require('../../tester/chrome-tester-client');
var CoverageFunction = require('./coverage-function');
var CoverageObject = (function () {
    function CoverageObject(name, pathTempFile, leenaConfig, originalAST, cb) {
        this.name = name;
        this.pathTempFile = pathTempFile;
        this.leenaConfig = leenaConfig;
        this.originalAST = originalAST;
        this.chromeClient = new ChromeClient({
            hostname: this.leenaConfig.chromeTester.testerServer.hostname,
            port: this.leenaConfig.chromeTester.testerServer.port
        });
        this.coverageFunctions = [];
        this.initializeChrome(cb);
    }
    CoverageObject.prototype.update = function () {
    };
    CoverageObject.prototype.containsFunction = function (functionName) {
        return this.getFunctionIndex(functionName) !== -1;
    };
    CoverageObject.prototype.executeFunction = function (functionName, cb) {
        var index = this.getFunctionIndex(functionName);
        var error;
        var that = this;
        if (index === -1) {
            throw new Error('Unable to execute function "' + functionName + '". It does not exist');
        }
        else if (index < 0 || index >= this.coverageFunctions.length) {
            throw new Error('Unable to execute function "' + functionName + '". Out of range');
        }
        this.chromeClient.getCoverageObject(this.name, function (err, res) {
            if (err) {
                error = new Error('Unable to establish connection to update the coverage object after function execution');
                cb(error, null);
            }
            else if (res) {
                try {
                    that.coverageFunctions[index].execute(res, cb);
                }
                catch (e) {
                    error = new Error('Unable to update the coverage object after function execution. Reason: ' + e.message);
                    cb(error, null);
                }
            }
        });
    };
    CoverageObject.prototype.getFunctionInstance = function (functionName) {
        var index = this.getFunctionIndex(functionName);
        if (index === -1) {
            throw new Error('Unable to get function instance. Function "' + functionName + '" does not exist');
        }
        else if (index < 0 || index >= this.coverageFunctions.length) {
            throw new Error('Unable to get function instance of function "' + functionName + '". Index out of range');
        }
        return this.coverageFunctions[index];
    };
    CoverageObject.prototype.updateFunctionInstance = function (functionName, functionI) {
        var index = this.getFunctionIndex(functionName);
        if (index === -1) {
            throw new Error('Unable to get function instance. Function "' + functionName + '" does not exist');
        }
        else if (index < 0 || index >= this.coverageFunctions.length) {
            throw new Error('Unable to get function instance of function "' + functionName + '". Index out of range');
        }
        this.coverageFunctions[index] = functionI;
    };
    CoverageObject.prototype.initializeChrome = function (cb) {
        var that = this;
        this.chromeClient.getCoverageObject(this.name, function (err, res) {
            if (err) {
                cb(err, null);
            }
            else if (res) {
                that.value = res;
                try {
                    that.parseCoverageObject();
                    cb(null, true);
                }
                catch (e) {
                    cb(e, null);
                }
            }
        });
    };
    CoverageObject.prototype.parseCoverageObject = function () {
        var pathCoverageObject;
        var functionMapObj;
        pathCoverageObject = this.value.path;
        if (pathCoverageObject !== this.pathTempFile) {
            throw new Error([
                'Property "path" is different from temporary path. (',
                pathCoverageObject,
                ', ',
                this.pathTempFile,
                ')'
            ].join(''));
        }
        functionMapObj = this.value.fnMap;
        for (var function_ in this.value.fnMap) {
            if (this.value.fnMap.hasOwnProperty(function_)) {
                try {
                    this.addFunction(parseInt(function_));
                }
                catch (e) {
                    throw e;
                }
            }
        }
    };
    CoverageObject.prototype.addFunction = function (functionKey) {
        var covFunction;
        try {
            covFunction = new CoverageFunction(functionKey, this.value.fnMap[functionKey].name, this.originalAST, this.pathTempFile, this.name);
            covFunction.setStartLocation(this.value.fnMap[functionKey].loc.start, this.value.fnMap[functionKey].loc.end);
            covFunction.setEndLocation(this.originalAST);
            covFunction.addStatements(this.value.s, this.value.statementMap);
            covFunction.addBranches(this.value.b, this.value.branchMap);
            this.coverageFunctions.push(covFunction);
        }
        catch (e) {
            throw e;
        }
    };
    CoverageObject.prototype.getFunctionIndex = function (functionName) {
        for (var k = 0; k < this.coverageFunctions.length; k++) {
            if (this.coverageFunctions[k].name === functionName) {
                return k;
            }
        }
        return -1;
    };
    return CoverageObject;
}());
module.exports = CoverageObject;
