"use strict";
var path = require("path");
var prepareInfoFileName = ".nsprepareinfo";
var ProjectChangesInfo = (function () {
    function ProjectChangesInfo(platform, force, skipModulesAndResources, $platformsData, $projectData, $devicePlatformsConstants, $options, $fs) {
        this.force = force;
        this.skipModulesAndResources = skipModulesAndResources;
        this.$platformsData = $platformsData;
        this.$projectData = $projectData;
        this.$devicePlatformsConstants = $devicePlatformsConstants;
        this.$options = $options;
        this.$fs = $fs;
        this.appFilesChanged = false;
        this.appResourcesChanged = false;
        this.modulesChanged = false;
        this.configChanged = false;
        var platformData = this.$platformsData.getPlatformData(platform);
        var buildInfoFile = path.join(platformData.projectRoot, prepareInfoFileName);
        if (force || !this.$fs.exists(buildInfoFile).wait()) {
            this.appFilesChanged = true;
            this.appResourcesChanged = true;
            this.modulesChanged = true;
            this.configChanged = true;
            this.prepareInfo = { time: "", bundle: $options.bundle, release: $options.release };
        }
        else {
            var outputProjectMtime = this.$fs.getFsStats(buildInfoFile).wait().mtime.getTime();
            this.prepareInfo = this.$fs.readJson(buildInfoFile).wait();
            this.appFilesChanged = this.containsNewerFiles(this.$projectData.appDirectoryPath, this.$projectData.appResourcesDirectoryPath, outputProjectMtime);
            if (!skipModulesAndResources) {
                this.appResourcesChanged = this.containsNewerFiles(this.$projectData.appResourcesDirectoryPath, null, outputProjectMtime);
                this.modulesChanged = this.containsNewerFiles(path.join(this.$projectData.projectDir, "node_modules"), null, outputProjectMtime);
                var platformResourcesDir = path.join(this.$projectData.appResourcesDirectoryPath, platformData.normalizedPlatformName);
                if (platform === this.$devicePlatformsConstants.iOS.toLowerCase()) {
                    this.configChanged = this.filesChanged([
                        this.$options.baseConfig || path.join(platformResourcesDir, platformData.configurationFileName),
                        path.join(platformResourcesDir, "LaunchScreen.storyboard"),
                        path.join(platformResourcesDir, "build.xcconfig")
                    ], outputProjectMtime);
                }
                else {
                    this.configChanged = this.filesChanged([
                        path.join(platformResourcesDir, platformData.configurationFileName),
                        path.join(platformResourcesDir, "app.gradle")
                    ], outputProjectMtime);
                }
            }
            if (this.$options.bundle !== this.prepareInfo.bundle || this.$options.release !== this.prepareInfo.release) {
                this.appFilesChanged = true;
                this.appResourcesChanged = true;
                this.modulesChanged = true;
                this.configChanged = true;
                this.prepareInfo.release = this.$options.release;
                this.prepareInfo.bundle = this.$options.bundle;
            }
            if (this.modulesChanged || this.appResourcesChanged) {
                this.configChanged = true;
            }
        }
        if (this.hasChanges) {
            this.prepareInfo.time = new Date().toString();
            this.$fs.writeJson(buildInfoFile, this.prepareInfo).wait();
        }
    }
    Object.defineProperty(ProjectChangesInfo.prototype, "hasChanges", {
        get: function () {
            return this.appFilesChanged || this.appResourcesChanged || this.modulesChanged || this.configChanged;
        },
        enumerable: true,
        configurable: true
    });
    ProjectChangesInfo.prototype.filesChanged = function (files, mtime) {
        for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
            var file = files_1[_i];
            if (this.$fs.exists(file).wait()) {
                var fileStats = this.$fs.getFsStats(file).wait();
                if (fileStats.mtime.getTime() > mtime) {
                    return true;
                }
            }
        }
        return false;
    };
    ProjectChangesInfo.prototype.containsNewerFiles = function (dir, skipDir, mtime) {
        var files = this.$fs.readDirectory(dir).wait();
        for (var _i = 0, files_2 = files; _i < files_2.length; _i++) {
            var file = files_2[_i];
            var filePath = path.join(dir, file);
            if (filePath === skipDir) {
                continue;
            }
            var fileStats = this.$fs.getFsStats(filePath).wait();
            if (fileStats.mtime.getTime() > mtime) {
                return true;
            }
            var lFileStats = this.$fs.getLsStats(filePath).wait();
            if (lFileStats.mtime.getTime() > mtime) {
                return true;
            }
            if (fileStats.isDirectory()) {
                if (this.containsNewerFiles(filePath, skipDir, mtime)) {
                    return true;
                }
            }
        }
        return false;
    };
    return ProjectChangesInfo;
}());
exports.ProjectChangesInfo = ProjectChangesInfo;
