"use strict";
var path = require("path");
var fs = require("fs");
var NodeModulesDependenciesBuilder = (function () {
    function NodeModulesDependenciesBuilder($fs) {
        this.$fs = $fs;
        this.seen = {};
        this.resolvedDependencies = [];
    }
    NodeModulesDependenciesBuilder.prototype.getProductionDependencies = function (projectPath) {
        var _this = this;
        this.projectPath = projectPath;
        this.rootNodeModulesPath = path.join(this.projectPath, "node_modules");
        var projectPackageJsonpath = path.join(this.projectPath, "package.json");
        var packageJsonContent = this.$fs.readJson(projectPackageJsonpath).wait();
        _.keys(packageJsonContent.dependencies).forEach(function (dependencyName) {
            var depth = 0;
            var directory = path.join(_this.rootNodeModulesPath, dependencyName);
            _this.traverseDependency(dependencyName, directory, depth);
        });
        return this.resolvedDependencies;
    };
    NodeModulesDependenciesBuilder.prototype.traverseDependency = function (name, currentModulePath, depth) {
        var modulePath = path.join(currentModulePath, "node_modules", name);
        var alternativeModulePath = path.join(this.rootNodeModulesPath, name);
        this.findModule(modulePath, alternativeModulePath, name, depth);
    };
    NodeModulesDependenciesBuilder.prototype.findModule = function (modulePath, alternativeModulePath, name, depth) {
        var exists = this.moduleExists(modulePath);
        if (exists) {
            if (this.seen[modulePath]) {
                return;
            }
            var dependency = this.addDependency(name, modulePath, depth + 1);
            this.readModuleDependencies(modulePath, depth + 1, dependency);
        }
        else {
            modulePath = alternativeModulePath;
            exists = this.moduleExists(modulePath);
            if (!exists) {
                return;
            }
            if (this.seen[modulePath]) {
                return;
            }
            var dependency = this.addDependency(name, modulePath, 0);
            this.readModuleDependencies(modulePath, 0, dependency);
        }
        this.seen[modulePath] = true;
    };
    NodeModulesDependenciesBuilder.prototype.readModuleDependencies = function (modulePath, depth, currentModule) {
        var _this = this;
        var packageJsonPath = path.join(modulePath, 'package.json');
        var packageJsonExists = fs.lstatSync(packageJsonPath).isFile();
        if (packageJsonExists) {
            var packageJsonContents = this.$fs.readJson(packageJsonPath).wait();
            if (!!packageJsonContents.nativescript) {
                currentModule.nativescript = packageJsonContents.nativescript;
            }
            _.keys(packageJsonContents.dependencies).forEach(function (dependencyName) {
                _this.traverseDependency(dependencyName, modulePath, depth);
            });
        }
    };
    NodeModulesDependenciesBuilder.prototype.addDependency = function (name, directory, depth) {
        var dependency = {
            name: name,
            directory: directory,
            depth: depth
        };
        this.resolvedDependencies.push(dependency);
        return dependency;
    };
    NodeModulesDependenciesBuilder.prototype.moduleExists = function (modulePath) {
        try {
            var exists = fs.lstatSync(modulePath);
            return exists.isDirectory();
        }
        catch (e) {
            return false;
        }
    };
    return NodeModulesDependenciesBuilder;
}());
exports.NodeModulesDependenciesBuilder = NodeModulesDependenciesBuilder;
$injector.register("nodeModulesDependenciesBuilder", NodeModulesDependenciesBuilder);
