"use strict";
const path = require("path");
const prepareInfoFileName = ".nsprepareinfo";
class ProjectChangesInfo {
    constructor(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;
        let platformData = this.$platformsData.getPlatformData(platform);
        let buildInfoFile = path.join(platformData.projectRoot, prepareInfoFileName);
        if (force || !this.$fs.exists(buildInfoFile)) {
            this.appFilesChanged = true;
            this.appResourcesChanged = true;
            this.modulesChanged = true;
            this.configChanged = true;
            this.prepareInfo = { time: "", bundle: $options.bundle, release: $options.release };
        }
        else {
            let outputProjectMtime = this.$fs.getFsStats(buildInfoFile).mtime.getTime();
            this.prepareInfo = this.$fs.readJson(buildInfoFile);
            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"), path.join(this.$projectData.projectDir, "node_modules", "tns-ios-inspector"), outputProjectMtime);
                let 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);
        }
    }
    get hasChanges() {
        return this.appFilesChanged || this.appResourcesChanged || this.modulesChanged || this.configChanged;
    }
    filesChanged(files, mtime) {
        for (let file of files) {
            if (this.$fs.exists(file)) {
                let fileStats = this.$fs.getFsStats(file);
                if (fileStats.mtime.getTime() > mtime) {
                    return true;
                }
            }
        }
        return false;
    }
    containsNewerFiles(dir, skipDir, mtime) {
        let files = this.$fs.readDirectory(dir);
        for (let file of files) {
            let filePath = path.join(dir, file);
            if (filePath === skipDir) {
                continue;
            }
            let fileStats = this.$fs.getFsStats(filePath);
            if (fileStats.mtime.getTime() > mtime) {
                return true;
            }
            let lFileStats = this.$fs.getLsStats(filePath);
            if (lFileStats.mtime.getTime() > mtime) {
                return true;
            }
            if (fileStats.isDirectory()) {
                if (this.containsNewerFiles(filePath, skipDir, mtime)) {
                    return true;
                }
            }
        }
        return false;
    }
}
exports.ProjectChangesInfo = ProjectChangesInfo;
