"use strict";
const constants = require("./constants");
const path = require("path");
const os_1 = require("os");
class ProjectData {
    constructor($fs, $errors, $logger, $projectHelper, $staticConfig, $options) {
        this.$fs = $fs;
        this.$errors = $errors;
        this.$logger = $logger;
        this.$projectHelper = $projectHelper;
        this.$staticConfig = $staticConfig;
        this.$options = $options;
    }
    initializeProjectData(projectDir) {
        projectDir = projectDir || this.$projectHelper.projectDir;
        if (projectDir) {
            this.initializeProjectDataCore(projectDir);
            let data = null;
            if (this.$fs.exists(this.projectFilePath)) {
                let fileContent = null;
                try {
                    fileContent = this.$fs.readJson(this.projectFilePath);
                    data = fileContent[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE];
                }
                catch (err) {
                    this.$errors.fail({
                        formatStr: "The project file %s is corrupted." + os_1.EOL +
                            "Consider restoring an earlier version from your source control or backup." + os_1.EOL +
                            "Additional technical info: %s",
                        suppressCommandHelp: true
                    }, this.projectFilePath, err.toString());
                }
                if (data) {
                    this.projectId = data.id;
                    this.dependencies = fileContent.dependencies;
                    this.devDependencies = fileContent.devDependencies;
                    this.projectType = this.getProjectType();
                }
                else {
                    this.tryToUpgradeProject();
                }
            }
        }
        else {
            this.tryToUpgradeProject();
        }
    }
    getProjectType() {
        let detectedProjectType = _.find(ProjectData.PROJECT_TYPES, (projectType) => projectType.isDefaultProjectType).type;
        const deps = _.keys(this.dependencies).concat(_.keys(this.devDependencies));
        _.each(ProjectData.PROJECT_TYPES, projectType => {
            if (_.some(projectType.requiredDependencies, requiredDependency => deps.indexOf(requiredDependency) !== -1)) {
                detectedProjectType = projectType.type;
                return false;
            }
        });
        return detectedProjectType;
    }
    throwNoProjectFoundError() {
        this.$errors.fail("No project found at or above '%s' and neither was a --path specified.", this.$options.path || path.resolve("."));
    }
    tryToUpgradeProject() {
        let projectDir = this.projectDir || path.resolve(this.$options.path || ".");
        let oldProjectFilePath = path.join(projectDir, ProjectData.OLD_PROJECT_FILE_NAME);
        if (this.$fs.exists(oldProjectFilePath)) {
            this.upgrade(projectDir, oldProjectFilePath);
        }
        else {
            this.throwNoProjectFoundError();
        }
    }
    upgrade(projectDir, oldProjectFilePath) {
        try {
            let oldProjectData = this.$fs.readJson(oldProjectFilePath);
            let newProjectFilePath = this.projectFilePath || path.join(projectDir, this.$staticConfig.PROJECT_FILE_NAME);
            let newProjectData = this.$fs.exists(newProjectFilePath) ? this.$fs.readJson(newProjectFilePath) : {};
            newProjectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE] = oldProjectData;
            this.$fs.writeJson(newProjectFilePath, newProjectData);
            this.projectId = newProjectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE].id;
            this.$fs.deleteFile(oldProjectFilePath);
        }
        catch (err) {
            this.$logger.out("An error occurred while upgrading your project.");
            throw err;
        }
        this.initializeProjectDataCore(projectDir);
        this.$logger.out("Successfully upgraded your project file.");
    }
    initializeProjectDataCore(projectDir) {
        this.projectDir = projectDir;
        this.projectName = this.$projectHelper.sanitizeName(path.basename(projectDir));
        this.platformsDir = path.join(projectDir, "platforms");
        this.projectFilePath = path.join(projectDir, this.$staticConfig.PROJECT_FILE_NAME);
        this.appDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME);
        this.appResourcesDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME);
    }
}
ProjectData.OLD_PROJECT_FILE_NAME = ".tnsproject";
ProjectData.PROJECT_TYPES = [
    {
        type: "Pure JavaScript",
        isDefaultProjectType: true
    },
    {
        type: "Angular",
        requiredDependencies: ["@angular/core", "nativescript-angular"]
    },
    {
        type: "Pure TypeScript",
        requiredDependencies: ["typescript", "nativescript-dev-typescript"]
    }
];
exports.ProjectData = ProjectData;
$injector.register("projectData", ProjectData);
