"use strict";
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var path = require("path");
var shell = require("shelljs");
var os = require("os");
var semver = require("semver");
var xcode = require("xcode");
var constants = require("../constants");
var helpers = require("../common/helpers");
var projectServiceBaseLib = require("./platform-project-service-base");
var Future = require("fibers/future");
var plist_merge_patch_1 = require("plist-merge-patch");
var os_1 = require("os");
var temp = require("temp");
var plist = require("plist");
var IOSProjectService = (function (_super) {
    __extends(IOSProjectService, _super);
    function IOSProjectService($projectData, $fs, $childProcess, $cocoapodsService, $errors, $logger, $iOSEmulatorServices, $iOSSimResolver, $options, $injector, $projectDataService, $prompter, $config, $devicePlatformsConstants, $devicesService, $mobileHelper, $pluginVariablesService, $xcprojService) {
        _super.call(this, $fs, $projectData, $projectDataService);
        this.$childProcess = $childProcess;
        this.$cocoapodsService = $cocoapodsService;
        this.$errors = $errors;
        this.$logger = $logger;
        this.$iOSEmulatorServices = $iOSEmulatorServices;
        this.$iOSSimResolver = $iOSSimResolver;
        this.$options = $options;
        this.$injector = $injector;
        this.$prompter = $prompter;
        this.$config = $config;
        this.$devicePlatformsConstants = $devicePlatformsConstants;
        this.$devicesService = $devicesService;
        this.$mobileHelper = $mobileHelper;
        this.$pluginVariablesService = $pluginVariablesService;
        this.$xcprojService = $xcprojService;
    }
    Object.defineProperty(IOSProjectService.prototype, "$npmInstallationManager", {
        get: function () {
            return this.$injector.resolve("npmInstallationManager");
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IOSProjectService.prototype, "platformData", {
        get: function () {
            var projectRoot = path.join(this.$projectData.platformsDir, "ios");
            return {
                frameworkPackageName: "tns-ios",
                normalizedPlatformName: "iOS",
                appDestinationDirectoryPath: path.join(projectRoot, this.$projectData.projectName),
                platformProjectService: this,
                emulatorServices: this.$iOSEmulatorServices,
                projectRoot: projectRoot,
                deviceBuildOutputPath: path.join(projectRoot, "build", "device"),
                emulatorBuildOutputPath: path.join(projectRoot, "build", "emulator"),
                validPackageNamesForDevice: [
                    this.$projectData.projectName + ".ipa"
                ],
                validPackageNamesForEmulator: [
                    this.$projectData.projectName + ".app"
                ],
                frameworkFilesExtensions: [".a", ".framework", ".bin"],
                frameworkDirectoriesExtensions: [".framework"],
                frameworkDirectoriesNames: ["Metadata", "metadataGenerator", "NativeScript", "internal"],
                targetedOS: ['darwin'],
                configurationFileName: "Info.plist",
                configurationFilePath: path.join(projectRoot, this.$projectData.projectName, this.$projectData.projectName + "-Info.plist"),
                relativeToFrameworkConfigurationFilePath: path.join("__PROJECT_NAME__", "__PROJECT_NAME__-Info.plist"),
                fastLivesyncFileExtensions: [".tiff", ".tif", ".jpg", "jpeg", "gif", ".png", ".bmp", ".BMPf", ".ico", ".cur", ".xbm"]
            };
        },
        enumerable: true,
        configurable: true
    });
    IOSProjectService.prototype.getAppResourcesDestinationDirectoryPath = function () {
        var _this = this;
        return (function () {
            var frameworkVersion = _this.getFrameworkVersion(_this.platformData.frameworkPackageName).wait();
            if (semver.lt(frameworkVersion, "1.3.0")) {
                return path.join(_this.platformData.projectRoot, _this.$projectData.projectName, "Resources", "icons");
            }
            return path.join(_this.platformData.projectRoot, _this.$projectData.projectName, "Resources");
        }).future()();
    };
    IOSProjectService.prototype.validate = function () {
        var _this = this;
        return (function () {
            try {
                _this.$childProcess.exec("which xcodebuild").wait();
            }
            catch (error) {
                _this.$errors.fail("Xcode is not installed. Make sure you have Xcode installed and added to your PATH");
            }
            var xcodeBuildVersion = _this.getXcodeVersion();
            if (helpers.versionCompare(xcodeBuildVersion, IOSProjectService.XCODEBUILD_MIN_VERSION) < 0) {
                _this.$errors.fail("NativeScript can only run in Xcode version %s or greater", IOSProjectService.XCODEBUILD_MIN_VERSION);
            }
        }).future()();
    };
    IOSProjectService.prototype.createProject = function (frameworkDir, frameworkVersion, pathToTemplate) {
        var _this = this;
        return (function () {
            _this.$fs.ensureDirectoryExists(path.join(_this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER)).wait();
            if (pathToTemplate) {
                _this.$fs.readDirectory(frameworkDir).wait()
                    .filter(function (dirName) { return dirName.indexOf(IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER) === -1; })
                    .forEach(function (dirName) { return shell.cp("-R", path.join(frameworkDir, dirName), _this.platformData.projectRoot); });
                shell.cp("-rf", path.join(pathToTemplate, "*"), _this.platformData.projectRoot);
            }
            else {
                shell.cp("-R", path.join(frameworkDir, "*"), _this.platformData.projectRoot);
            }
        }).future()();
    };
    IOSProjectService.prototype.interpolateData = function () {
        var _this = this;
        return (function () {
            var infoPlistFilePath = path.join(_this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER + "-Info.plist");
            _this.interpolateConfigurationFile(infoPlistFilePath).wait();
            var projectRootFilePath = path.join(_this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER);
            if (_this.$fs.exists(path.join(projectRootFilePath, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER + "-Info.plist")).wait()) {
                _this.replaceFileName("-Info.plist", projectRootFilePath).wait();
            }
            _this.replaceFileName("-Prefix.pch", projectRootFilePath).wait();
            var xcschemeDirPath = path.join(_this.platformData.projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER + IOSProjectService.XCODE_PROJECT_EXT_NAME, "xcshareddata/xcschemes");
            var xcschemeFilePath = path.join(xcschemeDirPath, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER + IOSProjectService.XCODE_SCHEME_EXT_NAME);
            if (_this.$fs.exists(xcschemeFilePath).wait()) {
                _this.$logger.debug("Found shared scheme at xcschemeFilePath, renaming to match project name.");
                _this.$logger.debug("Checkpoint 0");
                _this.replaceFileContent(xcschemeFilePath).wait();
                _this.$logger.debug("Checkpoint 1");
                _this.replaceFileName(IOSProjectService.XCODE_SCHEME_EXT_NAME, xcschemeDirPath).wait();
                _this.$logger.debug("Checkpoint 2");
            }
            else {
                _this.$logger.debug("Copying xcscheme from template not found at " + xcschemeFilePath);
            }
            _this.replaceFileName(IOSProjectService.XCODE_PROJECT_EXT_NAME, _this.platformData.projectRoot).wait();
            var pbxprojFilePath = _this.pbxProjPath;
            _this.replaceFileContent(pbxprojFilePath).wait();
        }).future()();
    };
    IOSProjectService.prototype.interpolateConfigurationFile = function (configurationFilePath) {
        var _this = this;
        return (function () {
            shell.sed('-i', "__CFBUNDLEIDENTIFIER__", _this.$projectData.projectId, configurationFilePath || _this.platformData.configurationFilePath);
        }).future()();
    };
    IOSProjectService.prototype.afterCreateProject = function (projectRoot) {
        var _this = this;
        return (function () {
            _this.$fs.rename(path.join(projectRoot, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER), path.join(projectRoot, _this.$projectData.projectName)).wait();
        }).future()();
    };
    IOSProjectService.prototype.archive = function (options) {
        var _this = this;
        return (function () {
            var projectRoot = _this.platformData.projectRoot;
            var archivePath = options && options.archivePath ? path.resolve(options.archivePath) : path.join(projectRoot, "/build/archive/", _this.$projectData.projectName + ".xcarchive");
            var args = ["archive", "-archivePath", archivePath]
                .concat(_this.xcbuildProjectArgs(projectRoot, "scheme"));
            _this.$childProcess.spawnFromEvent("xcodebuild", args, "exit", { cwd: _this.$options, stdio: 'inherit' }).wait();
            return archivePath;
        }).future()();
    };
    IOSProjectService.prototype.exportArchive = function (options) {
        var _this = this;
        return (function () {
            var projectRoot = _this.platformData.projectRoot;
            var archivePath = options.archivePath;
            var exportPath = path.resolve(options.exportDir || path.join(projectRoot, "/build/archive"));
            var exportFile = path.join(exportPath, _this.$projectData.projectName + ".ipa");
            var plistTemplate = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n";
            if (options && options.teamID) {
                plistTemplate += "    <key>teamID</key>\n    <string>" + options.teamID + "</string>\n";
            }
            plistTemplate += "    <key>method</key>\n    <string>app-store</string>\n    <key>uploadBitcode</key>\n    <false/>\n    <key>uploadSymbols</key>\n    <false/>\n</dict>\n</plist>";
            temp.track();
            var exportOptionsPlist = temp.path({ prefix: "export-", suffix: ".plist" });
            _this.$fs.writeFile(exportOptionsPlist, plistTemplate).wait();
            var args = ["-exportArchive",
                "-archivePath", archivePath,
                "-exportPath", exportPath,
                "-exportOptionsPlist", exportOptionsPlist
            ];
            _this.$childProcess.spawnFromEvent("xcodebuild", args, "exit", { cwd: _this.$options, stdio: 'inherit' }).wait();
            return exportFile;
        }).future()();
    };
    IOSProjectService.prototype.xcbuildProjectArgs = function (projectRoot, product) {
        var xcworkspacePath = path.join(projectRoot, this.$projectData.projectName + ".xcworkspace");
        if (this.$fs.exists(xcworkspacePath).wait()) {
            return ["-workspace", xcworkspacePath, product ? "-" + product : "-scheme", this.$projectData.projectName];
        }
        else {
            var xcodeprojPath = path.join(projectRoot, this.$projectData.projectName + ".xcodeproj");
            return ["-project", xcodeprojPath, product ? "-" + product : "-target", this.$projectData.projectName];
        }
    };
    IOSProjectService.prototype.buildProject = function (projectRoot, buildConfig) {
        var _this = this;
        return (function () {
            var basicArgs = [
                "-configuration", _this.$options.release ? "Release" : "Debug",
                "build",
                'SHARED_PRECOMPS_DIR=' + path.join(projectRoot, 'build', 'sharedpch')
            ];
            basicArgs = basicArgs.concat(_this.xcbuildProjectArgs(projectRoot));
            var frameworkVersion = _this.getFrameworkVersion(_this.platformData.frameworkPackageName).wait();
            if (semver.lt(frameworkVersion, "1.4.0")) {
                basicArgs.push("-xcconfig", path.join(projectRoot, _this.$projectData.projectName, "build.xcconfig"));
            }
            var args = [];
            var buildForDevice = _this.$options.forDevice || (buildConfig && buildConfig.buildForDevice);
            if (buildForDevice) {
                var defaultArchitectures = [
                    'ARCHS=armv7 arm64',
                    'VALID_ARCHS=armv7 arm64'
                ];
                args = basicArgs.concat([
                    "-sdk", "iphoneos",
                    "CONFIGURATION_BUILD_DIR=" + path.join(projectRoot, "build", "device")
                ]);
                args = args.concat((buildConfig && buildConfig.architectures) || defaultArchitectures);
                var xcodeBuildVersion = _this.getXcodeVersion();
                if (helpers.versionCompare(xcodeBuildVersion, "8.0") >= 0) {
                    var teamId = _this.getDevelopmentTeam();
                    if (teamId) {
                        args = args.concat("DEVELOPMENT_TEAM=" + teamId);
                    }
                }
            }
            else {
                args = basicArgs.concat([
                    "-sdk", "iphonesimulator",
                    "ARCHS=i386 x86_64",
                    "VALID_ARCHS=i386 x86_64",
                    "ONLY_ACTIVE_ARCH=NO",
                    "CONFIGURATION_BUILD_DIR=" + path.join(projectRoot, "build", "emulator"),
                    "CODE_SIGN_IDENTITY="
                ]);
            }
            if (buildConfig && buildConfig.codeSignIdentity) {
                args.push("CODE_SIGN_IDENTITY=" + buildConfig.codeSignIdentity);
            }
            if (buildConfig && buildConfig.mobileProvisionIdentifier) {
                args.push("PROVISIONING_PROFILE=" + buildConfig.mobileProvisionIdentifier);
            }
            _this.$childProcess.spawnFromEvent("xcodebuild", args, "exit", { cwd: _this.$options, stdio: 'inherit' }).wait();
            if (buildForDevice) {
                var buildOutputPath = path.join(projectRoot, "build", "device");
                var xcrunArgs = [
                    "-sdk", "iphoneos",
                    "PackageApplication",
                    "-v", path.join(buildOutputPath, _this.$projectData.projectName + ".app"),
                    "-o", path.join(buildOutputPath, _this.$projectData.projectName + ".ipa")
                ];
                _this.$childProcess.spawnFromEvent("xcrun", xcrunArgs, "exit", { cwd: _this.$options, stdio: 'inherit' }).wait();
            }
        }).future()();
    };
    IOSProjectService.prototype.buildForDeploy = function (platform, buildConfig) {
        var _this = this;
        if (this.$options.release) {
            return this.buildProject(this.platformData.projectRoot, buildConfig);
        }
        var devicesArchitectures = _(this.$devicesService.getDeviceInstances())
            .filter(function (d) { return _this.$mobileHelper.isiOSPlatform(d.deviceInfo.platform); })
            .map(function (d) { return d.deviceInfo.activeArchitecture; })
            .uniq()
            .value();
        var architectures = [
            ("ARCHS=" + devicesArchitectures.join(" ")),
            ("VALID_ARCHS=" + devicesArchitectures.join(" "))
        ];
        if (devicesArchitectures.length > 1) {
            architectures.push('ONLY_ACTIVE_ARCH=NO');
        }
        buildConfig = buildConfig || {};
        buildConfig.architectures = architectures;
        return this.buildProject(this.platformData.projectRoot, buildConfig);
    };
    IOSProjectService.prototype.isPlatformPrepared = function (projectRoot) {
        return this.$fs.exists(path.join(projectRoot, this.$projectData.projectName, constants.APP_FOLDER_NAME));
    };
    IOSProjectService.prototype.deploy = function (deviceIdentifier) {
        return Future.fromResult();
    };
    IOSProjectService.prototype.addFramework = function (frameworkPath) {
        var _this = this;
        return (function () {
            _this.validateFramework(frameworkPath).wait();
            var project = _this.createPbxProj();
            var frameworkName = path.basename(frameworkPath, path.extname(frameworkPath));
            var frameworkBinaryPath = path.join(frameworkPath, frameworkName);
            var isDynamic = _.includes(_this.$childProcess.spawnFromEvent("otool", ["-Vh", frameworkBinaryPath], "close").wait().stdout, " DYLIB ");
            var frameworkAddOptions = { customFramework: true };
            if (isDynamic) {
                frameworkAddOptions["embed"] = true;
            }
            var frameworkRelativePath = '$(SRCROOT)/' + _this.getLibSubpathRelativeToProjectPath(frameworkPath);
            project.addFramework(frameworkRelativePath, frameworkAddOptions);
            _this.savePbxProj(project).wait();
        }).future()();
    };
    IOSProjectService.prototype.addStaticLibrary = function (staticLibPath) {
        var _this = this;
        return (function () {
            _this.validateStaticLibrary(staticLibPath).wait();
            var libraryName = path.basename(staticLibPath, ".a");
            var headersSubpath = path.join(path.dirname(staticLibPath), "include", libraryName);
            var project = _this.createPbxProj();
            var relativeStaticLibPath = _this.getLibSubpathRelativeToProjectPath(staticLibPath);
            project.addFramework(relativeStaticLibPath);
            var relativeHeaderSearchPath = path.join(_this.getLibSubpathRelativeToProjectPath(headersSubpath));
            project.addToHeaderSearchPaths({ relativePath: relativeHeaderSearchPath });
            _this.generateModulemap(headersSubpath, libraryName);
            _this.savePbxProj(project).wait();
        }).future()();
    };
    IOSProjectService.prototype.canUpdatePlatform = function (installedModuleDir) {
        var _this = this;
        return (function () {
            var currentXcodeProjectFile = _this.buildPathToCurrentXcodeProjectFile();
            var currentXcodeProjectFileContent = _this.$fs.readFile(currentXcodeProjectFile).wait();
            var newXcodeProjectFile = _this.buildPathToNewXcodeProjectFile(installedModuleDir);
            _this.replaceFileContent(newXcodeProjectFile).wait();
            var newXcodeProjectFileContent = _this.$fs.readFile(newXcodeProjectFile).wait();
            var contentIsTheSame = currentXcodeProjectFileContent.toString() === newXcodeProjectFileContent.toString();
            if (!contentIsTheSame) {
                _this.$logger.warn("The content of the current project file: " + currentXcodeProjectFile + " and the new project file: " + newXcodeProjectFile + " is different.");
            }
            return contentIsTheSame;
        }).future()();
    };
    IOSProjectService.prototype.provideLaunchScreenIfMissing = function () {
        try {
            this.$logger.trace("Checking if we need to provide compatability LaunchScreen.xib");
            var platformData = this.platformData;
            var projectPath = path.join(platformData.projectRoot, this.$projectData.projectName);
            var projectPlist = this.getInfoPlistPath();
            var plistContent = plist.parse(this.$fs.readText(projectPlist).wait());
            var storyName = plistContent["UILaunchStoryboardName"];
            this.$logger.trace("Examining " + projectPlist + " UILaunchStoryboardName: \"" + storyName + "\".");
            if (storyName !== "LaunchScreen") {
                this.$logger.trace("The project has its UILaunchStoryboardName set to " + storyName + " which is not the pre v2.1.0 default LaunchScreen, probably the project is migrated so we are good to go.");
                return;
            }
            var expectedStoryPath = path.join(projectPath, "Resources", "LaunchScreen.storyboard");
            if (this.$fs.exists(expectedStoryPath).wait()) {
                this.$logger.trace("LaunchScreen.storyboard was found. Project is up to date.");
                return;
            }
            this.$logger.trace("LaunchScreen file not found at: " + expectedStoryPath);
            var expectedXibPath = path.join(projectPath, "en.lproj", "LaunchScreen.xib");
            if (this.$fs.exists(expectedXibPath).wait()) {
                this.$logger.trace("Obsolete LaunchScreen.xib was found. It'k OK, we are probably running with iOS runtime from pre v2.1.0.");
                return;
            }
            this.$logger.trace("LaunchScreen file not found at: " + expectedXibPath);
            var isTheLaunchScreenFile = function (fileName) { return fileName === "LaunchScreen.xib" || fileName === "LaunchScreen.storyboard"; };
            var matches = this.$fs.enumerateFilesInDirectorySync(projectPath, isTheLaunchScreenFile, { enumerateDirectories: false });
            if (matches.length > 0) {
                this.$logger.trace("Found LaunchScreen by slowly traversing all files here: " + matches + "\nConsider moving the LaunchScreen so it could be found at: " + expectedStoryPath);
                return;
            }
            var compatabilityXibPath = path.join(projectPath, "Resources", "LaunchScreen.xib");
            this.$logger.warn("Failed to find LaunchScreen.storyboard but it was specified in the Info.plist.\nConsider updating the resources in app/App_Resources/iOS/.\nA good starting point would be to create a new project and diff the changes with your current one.\nAlso the following repo may be helpful: https://github.com/NativeScript/template-hello-world/tree/master/App_Resources/iOS\nWe will now place an empty obsolete compatability white screen LauncScreen.xib for you in " + path.relative(this.$projectData.projectDir, compatabilityXibPath) + " so your app may appear as it did in pre v2.1.0 versions of the ios runtime.");
            var content = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"6751\" systemVersion=\"14A389\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"6736\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\"/>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <view contentMode=\"scaleToFill\" id=\"iN0-l3-epB\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"480\"/>\n            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n            <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"calibratedWhite\"/>\n            <nil key=\"simulatedStatusBarMetrics\"/>\n            <freeformSimulatedSizeMetrics key=\"simulatedDestinationMetrics\"/>\n            <point key=\"canvasLocation\" x=\"548\" y=\"455\"/>\n        </view>\n    </objects>\n</document>";
            try {
                this.$fs.createDirectory(path.dirname(compatabilityXibPath)).wait();
                this.$fs.writeFile(compatabilityXibPath, content).wait();
            }
            catch (e) {
                this.$logger.warn("We have failed to add compatability LaunchScreen.xib due to: " + e);
            }
        }
        catch (e) {
            this.$logger.warn("We have failed to check if we need to add a compatability LaunchScreen.xib due to: " + e);
        }
    };
    IOSProjectService.prototype.prepareProject = function () {
        var _this = this;
        return (function () {
            var project = _this.createPbxProj();
            _this.provideLaunchScreenIfMissing();
            var resources = project.pbxGroupByName("Resources");
            if (resources) {
                var references_1 = project.pbxFileReferenceSection();
                var xcodeProjectImages = _.map(resources.children, function (resource) { return _this.replace(references_1[resource.value].name); });
                _this.$logger.trace("Images from Xcode project");
                _this.$logger.trace(xcodeProjectImages);
                var appResourcesImages = _this.$fs.readDirectory(_this.getAppResourcesDestinationDirectoryPath().wait()).wait();
                _this.$logger.trace("Current images from App_Resources");
                _this.$logger.trace(appResourcesImages);
                var imagesToAdd = _.difference(appResourcesImages, xcodeProjectImages);
                _this.$logger.trace("New images to add into xcode project: " + imagesToAdd.join(", "));
                _.each(imagesToAdd, function (image) { return project.addResourceFile(path.relative(_this.platformData.projectRoot, path.join(_this.getAppResourcesDestinationDirectoryPath().wait(), image))); });
                var imagesToRemove = _.difference(xcodeProjectImages, appResourcesImages);
                _this.$logger.trace("Images to remove from xcode project: " + imagesToRemove.join(", "));
                _.each(imagesToRemove, function (image) { return project.removeResourceFile(path.join(_this.getAppResourcesDestinationDirectoryPath().wait(), image)); });
                _this.savePbxProj(project).wait();
            }
        }).future()();
    };
    IOSProjectService.prototype.prepareAppResources = function (appResourcesDirectoryPath) {
        var _this = this;
        return (function () {
            var platformFolder = path.join(appResourcesDirectoryPath, _this.platformData.normalizedPlatformName);
            var filterFile = function (filename) { return _this.$fs.deleteFile(path.join(platformFolder, filename)).wait(); };
            filterFile(_this.platformData.configurationFileName);
            _this.$fs.deleteDirectory(_this.getAppResourcesDestinationDirectoryPath().wait()).wait();
        }).future()();
    };
    IOSProjectService.prototype.processConfigurationFilesFromAppResources = function () {
        var _this = this;
        return (function () {
            _this.mergeInfoPlists().wait();
            _this.mergeProjectXcconfigFiles().wait();
            _(_this.getAllInstalledPlugins().wait())
                .map(function (pluginData) { return _this.$pluginVariablesService.interpolatePluginVariables(pluginData, _this.platformData.configurationFilePath).wait(); })
                .value();
            _this.$pluginVariablesService.interpolateAppIdentifier(_this.platformData.configurationFilePath).wait();
        }).future()();
    };
    IOSProjectService.prototype.getInfoPlistPath = function () {
        return this.$options.baseConfig ||
            path.join(this.$projectData.projectDir, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME, this.platformData.normalizedPlatformName, this.platformData.configurationFileName);
    };
    IOSProjectService.prototype.ensureConfigurationFileInAppResources = function () {
        return Future.fromResult();
    };
    IOSProjectService.prototype.mergeInfoPlists = function () {
        var _this = this;
        return (function () {
            var projectDir = _this.$projectData.projectDir;
            var infoPlistPath = _this.$options.baseConfig || path.join(projectDir, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME, _this.platformData.normalizedPlatformName, _this.platformData.configurationFileName);
            _this.ensureConfigurationFileInAppResources().wait();
            if (!_this.$fs.exists(infoPlistPath).wait()) {
                _this.$logger.trace("Info.plist: No app/App_Resources/iOS/Info.plist found, falling back to pre-1.6.0 Info.plist behavior.");
                return;
            }
            var session = new plist_merge_patch_1.PlistSession({ log: function (txt) { return _this.$logger.trace("Info.plist: " + txt); } });
            var makePatch = function (plistPath) {
                if (!_this.$fs.exists(plistPath).wait()) {
                    _this.$logger.trace("No plist found at: " + plistPath);
                    return;
                }
                _this.$logger.trace("Schedule merge plist at: " + plistPath);
                session.patch({
                    name: path.relative(projectDir, plistPath),
                    read: function () { return _this.$fs.readFile(plistPath).wait().toString(); }
                });
            };
            var allPlugins = _this.getAllInstalledPlugins().wait();
            for (var _i = 0, allPlugins_1 = allPlugins; _i < allPlugins_1.length; _i++) {
                var plugin = allPlugins_1[_i];
                var pluginInfoPlistPath = path.join(plugin.pluginPlatformsFolderPath(IOSProjectService.IOS_PLATFORM_NAME), _this.platformData.configurationFileName);
                makePatch(pluginInfoPlistPath);
            }
            makePatch(infoPlistPath);
            if (_this.$projectData.projectId) {
                session.patch({
                    name: "CFBundleIdentifier from package.json nativescript.id",
                    read: function () {
                        return ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\t\t\t\t\t\t<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n\t\t\t\t\t\t<plist version=\"1.0\">\n\t\t\t\t\t\t<dict>\n\t\t\t\t\t\t\t<key>CFBundleIdentifier</key>\n\t\t\t\t\t\t\t<string>" + _this.$projectData.projectId + "</string>\n\t\t\t\t\t\t</dict>\n\t\t\t\t\t\t</plist>");
                    }
                });
            }
            var plistContent = session.build();
            _this.$logger.trace("Info.plist: Write to: " + _this.platformData.configurationFilePath);
            _this.$fs.writeFile(_this.platformData.configurationFilePath, plistContent).wait();
        }).future()();
    };
    IOSProjectService.prototype.getAllInstalledPlugins = function () {
        return this.$injector.resolve("pluginsService").getAllInstalledPlugins();
    };
    Object.defineProperty(IOSProjectService.prototype, "xcodeprojPath", {
        get: function () {
            return path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IOSProjectService.prototype, "projectPodFilePath", {
        get: function () {
            return path.join(this.platformData.projectRoot, "Podfile");
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IOSProjectService.prototype, "pluginsDebugXcconfigFilePath", {
        get: function () {
            return path.join(this.platformData.projectRoot, "plugins-debug.xcconfig");
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(IOSProjectService.prototype, "pluginsReleaseXcconfigFilePath", {
        get: function () {
            return path.join(this.platformData.projectRoot, "plugins-release.xcconfig");
        },
        enumerable: true,
        configurable: true
    });
    IOSProjectService.prototype.replace = function (name) {
        if (_.startsWith(name, '"')) {
            name = name.substr(1, name.length - 2);
        }
        return name.replace(/\\\"/g, "\"");
    };
    IOSProjectService.prototype.getLibSubpathRelativeToProjectPath = function (targetPath) {
        var frameworkPath = path.relative(this.platformData.projectRoot, targetPath);
        return frameworkPath;
    };
    Object.defineProperty(IOSProjectService.prototype, "pbxProjPath", {
        get: function () {
            return path.join(this.xcodeprojPath, "project.pbxproj");
        },
        enumerable: true,
        configurable: true
    });
    IOSProjectService.prototype.createPbxProj = function () {
        var project = new xcode.project(this.pbxProjPath);
        project.parseSync();
        return project;
    };
    IOSProjectService.prototype.savePbxProj = function (project) {
        return this.$fs.writeFile(this.pbxProjPath, project.writeSync());
    };
    IOSProjectService.prototype.preparePluginNativeCode = function (pluginData, opts) {
        var _this = this;
        return (function () {
            var pluginPlatformsFolderPath = pluginData.pluginPlatformsFolderPath(IOSProjectService.IOS_PLATFORM_NAME);
            _this.prepareFrameworks(pluginPlatformsFolderPath, pluginData).wait();
            _this.prepareStaticLibs(pluginPlatformsFolderPath, pluginData).wait();
            _this.prepareCocoapods(pluginPlatformsFolderPath).wait();
        }).future()();
    };
    IOSProjectService.prototype.removePluginNativeCode = function (pluginData) {
        var _this = this;
        return (function () {
            var pluginPlatformsFolderPath = pluginData.pluginPlatformsFolderPath(IOSProjectService.IOS_PLATFORM_NAME);
            _this.removeFrameworks(pluginPlatformsFolderPath, pluginData).wait();
            _this.removeStaticLibs(pluginPlatformsFolderPath, pluginData).wait();
            _this.removeCocoapods(pluginPlatformsFolderPath).wait();
        }).future()();
    };
    IOSProjectService.prototype.afterPrepareAllPlugins = function () {
        var _this = this;
        return (function () {
            if (_this.$fs.exists(_this.projectPodFilePath).wait()) {
                var projectPodfileContent = _this.$fs.readText(_this.projectPodFilePath).wait();
                _this.$logger.trace("Project Podfile content");
                _this.$logger.trace(projectPodfileContent);
                var firstPostInstallIndex = projectPodfileContent.indexOf(IOSProjectService.PODFILE_POST_INSTALL_SECTION_NAME);
                if (firstPostInstallIndex !== -1 && firstPostInstallIndex !== projectPodfileContent.lastIndexOf(IOSProjectService.PODFILE_POST_INSTALL_SECTION_NAME)) {
                    _this.$cocoapodsService.mergePodfileHookContent(IOSProjectService.PODFILE_POST_INSTALL_SECTION_NAME, _this.projectPodFilePath).wait();
                }
                var xcuserDataPath = path.join(_this.xcodeprojPath, "xcuserdata");
                var sharedDataPath = path.join(_this.xcodeprojPath, "xcshareddata");
                if (!_this.$fs.exists(xcuserDataPath).wait() && !_this.$fs.exists(sharedDataPath).wait()) {
                    _this.$logger.info("Creating project scheme...");
                    _this.checkIfXcodeprojIsRequired().wait();
                    var createSchemeRubyScript = "ruby -e \"require 'xcodeproj'; xcproj = Xcodeproj::Project.open('" + _this.$projectData.projectName + ".xcodeproj'); xcproj.recreate_user_schemes; xcproj.save\"";
                    _this.$childProcess.exec(createSchemeRubyScript, { cwd: _this.platformData.projectRoot }).wait();
                }
                _this.executePodInstall().wait();
            }
        }).future()();
    };
    IOSProjectService.prototype.beforePrepareAllPlugins = function () {
        return Future.fromResult();
    };
    IOSProjectService.prototype.getAllLibsForPluginWithFileExtension = function (pluginData, fileExtension) {
        var filterCallback = function (fileName, pluginPlatformsFolderPath) { return path.extname(fileName) === fileExtension; };
        return this.getAllNativeLibrariesForPlugin(pluginData, IOSProjectService.IOS_PLATFORM_NAME, filterCallback);
    };
    ;
    IOSProjectService.prototype.buildPathToCurrentXcodeProjectFile = function () {
        return path.join(this.$projectData.platformsDir, "ios", this.$projectData.projectName + ".xcodeproj", "project.pbxproj");
    };
    IOSProjectService.prototype.buildPathToNewXcodeProjectFile = function (newModulesDir) {
        return path.join(newModulesDir, constants.PROJECT_FRAMEWORK_FOLDER_NAME, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER + ".xcodeproj", "project.pbxproj");
    };
    IOSProjectService.prototype.validateFramework = function (libraryPath) {
        var _this = this;
        return (function () {
            var infoPlistPath = path.join(libraryPath, "Info.plist");
            if (!_this.$fs.exists(infoPlistPath).wait()) {
                _this.$errors.failWithoutHelp("The bundle at %s does not contain an Info.plist file.", libraryPath);
            }
            var packageType = _this.$childProcess.spawnFromEvent("/usr/libexec/PlistBuddy", ["-c", "Print :CFBundlePackageType", infoPlistPath], "close").wait().stdout.trim();
            if (packageType !== "FMWK") {
                _this.$errors.failWithoutHelp("The bundle at %s does not appear to be a dynamic framework.", libraryPath);
            }
        }).future()();
    };
    IOSProjectService.prototype.validateStaticLibrary = function (libraryPath) {
        var _this = this;
        return (function () {
            if (path.extname(libraryPath) !== ".a") {
                _this.$errors.failWithoutHelp("The bundle at " + libraryPath + " does not contain a valid static library in the '.a' file format.");
            }
            var expectedArchs = ["armv7", "arm64", "i386"];
            var archsInTheFatFile = _this.$childProcess.exec("lipo -i " + libraryPath).wait();
            expectedArchs.forEach(function (expectedArch) {
                if (archsInTheFatFile.indexOf(expectedArch) < 0) {
                    _this.$errors.failWithoutHelp("The static library at " + libraryPath + " is not built for one or more of the following required architectures: " + expectedArchs.join(", ") + ". The static library must be built for all required architectures.");
                }
            });
        }).future()();
    };
    IOSProjectService.prototype.replaceFileContent = function (file) {
        var _this = this;
        return (function () {
            var fileContent = _this.$fs.readText(file).wait();
            var replacedContent = helpers.stringReplaceAll(fileContent, IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER, _this.$projectData.projectName);
            _this.$fs.writeFile(file, replacedContent).wait();
        }).future()();
    };
    IOSProjectService.prototype.replaceFileName = function (fileNamePart, fileRootLocation) {
        var _this = this;
        return (function () {
            var oldFileName = IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER + fileNamePart;
            var newFileName = _this.$projectData.projectName + fileNamePart;
            _this.$fs.rename(path.join(fileRootLocation, oldFileName), path.join(fileRootLocation, newFileName)).wait();
        }).future()();
    };
    IOSProjectService.prototype.executePodInstall = function () {
        var _this = this;
        return (function () {
            try {
                _this.$childProcess.exec("gem which cocoapods").wait();
                _this.$childProcess.exec("gem which xcodeproj").wait();
            }
            catch (e) {
                _this.$errors.failWithoutHelp("CocoaPods or ruby gem 'xcodeproj' is not installed. Run `sudo gem install cocoapods` and try again.");
            }
            _this.$xcprojService.verifyXcproj(true).wait();
            _this.$logger.info("Installing pods...");
            var podTool = _this.$config.USE_POD_SANDBOX ? "sandbox-pod" : "pod";
            var childProcess = _this.$childProcess.spawnFromEvent(podTool, ["install"], "close", { cwd: _this.platformData.projectRoot, stdio: ['pipe', process.stdout, 'pipe'] }).wait();
            if (childProcess.stderr) {
                var warnings = childProcess.stderr.match(/(\u001b\[(?:\d*;){0,5}\d*m[\s\S]+?\u001b\[(?:\d*;){0,5}\d*m)|(\[!\].*?\n)|(.*?warning.*)/gi);
                _.each(warnings, function (warning) {
                    _this.$logger.warnWithLabel(warning.replace("\n", ""));
                });
                var errors_1 = childProcess.stderr;
                _.each(warnings, function (warning) {
                    errors_1 = errors_1.replace(warning, "");
                });
                if (errors_1.trim()) {
                    _this.$errors.failWithoutHelp("Pod install command failed. Error output: " + errors_1);
                }
            }
            if (_this.$xcprojService.getXcprojInfo().wait().shouldUseXcproj) {
                _this.$childProcess.spawnFromEvent("xcproj", ["--project", _this.xcodeprojPath, "touch"], "close").wait();
            }
            return childProcess;
        }).future()();
    };
    IOSProjectService.prototype.prepareFrameworks = function (pluginPlatformsFolderPath, pluginData) {
        var _this = this;
        return (function () {
            _.each(_this.getAllLibsForPluginWithFileExtension(pluginData, ".framework").wait(), function (fileName) { return _this.addFramework(path.join(pluginPlatformsFolderPath, fileName)).wait(); });
        }).future()();
    };
    IOSProjectService.prototype.prepareStaticLibs = function (pluginPlatformsFolderPath, pluginData) {
        var _this = this;
        return (function () {
            _.each(_this.getAllLibsForPluginWithFileExtension(pluginData, ".a").wait(), function (fileName) { return _this.addStaticLibrary(path.join(pluginPlatformsFolderPath, fileName)).wait(); });
        }).future()();
    };
    IOSProjectService.prototype.prepareCocoapods = function (pluginPlatformsFolderPath, opts) {
        var _this = this;
        return (function () {
            var pluginPodFilePath = path.join(pluginPlatformsFolderPath, "Podfile");
            if (_this.$fs.exists(pluginPodFilePath).wait()) {
                var pluginPodFileContent = _this.$fs.readText(pluginPodFilePath).wait(), pluginPodFilePreparedContent = _this.buildPodfileContent(pluginPodFilePath, pluginPodFileContent), projectPodFileContent = _this.$fs.exists(_this.projectPodFilePath).wait() ? _this.$fs.readText(_this.projectPodFilePath).wait() : "";
                if (!~projectPodFileContent.indexOf(pluginPodFilePreparedContent)) {
                    var podFileHeader = _this.$cocoapodsService.getPodfileHeader(_this.$projectData.projectName), podFileFooter = _this.$cocoapodsService.getPodfileFooter();
                    if (_.startsWith(projectPodFileContent, podFileHeader)) {
                        projectPodFileContent = projectPodFileContent.substr(podFileHeader.length);
                    }
                    if (_.endsWith(projectPodFileContent, podFileFooter)) {
                        projectPodFileContent = projectPodFileContent.substr(0, projectPodFileContent.length - podFileFooter.length);
                    }
                    var contentToWrite = "" + podFileHeader + projectPodFileContent + pluginPodFilePreparedContent + podFileFooter;
                    _this.$fs.writeFile(_this.projectPodFilePath, contentToWrite).wait();
                    var project = _this.createPbxProj();
                    _this.savePbxProj(project).wait();
                }
            }
            if (opts && opts.executePodInstall && _this.$fs.exists(pluginPodFilePath).wait()) {
                _this.executePodInstall().wait();
            }
        }).future()();
    };
    IOSProjectService.prototype.removeFrameworks = function (pluginPlatformsFolderPath, pluginData) {
        var _this = this;
        return (function () {
            var project = _this.createPbxProj();
            _.each(_this.getAllLibsForPluginWithFileExtension(pluginData, ".framework").wait(), function (fileName) {
                var relativeFrameworkPath = _this.getLibSubpathRelativeToProjectPath(fileName);
                project.removeFramework(relativeFrameworkPath, { customFramework: true, embed: true });
            });
            _this.savePbxProj(project).wait();
        }).future()();
    };
    IOSProjectService.prototype.removeStaticLibs = function (pluginPlatformsFolderPath, pluginData) {
        var _this = this;
        return (function () {
            var project = _this.createPbxProj();
            _.each(_this.getAllLibsForPluginWithFileExtension(pluginData, ".a").wait(), function (fileName) {
                var staticLibPath = path.join(pluginPlatformsFolderPath, fileName);
                var relativeStaticLibPath = _this.getLibSubpathRelativeToProjectPath(path.basename(staticLibPath));
                project.removeFramework(relativeStaticLibPath);
                var headersSubpath = path.join("include", path.basename(staticLibPath, ".a"));
                var relativeHeaderSearchPath = path.join(_this.getLibSubpathRelativeToProjectPath(headersSubpath));
                project.removeFromHeaderSearchPaths({ relativePath: relativeHeaderSearchPath });
            });
            _this.savePbxProj(project).wait();
        }).future()();
    };
    IOSProjectService.prototype.removeCocoapods = function (pluginPlatformsFolderPath) {
        var _this = this;
        return (function () {
            var pluginPodFilePath = path.join(pluginPlatformsFolderPath, "Podfile");
            if (_this.$fs.exists(pluginPodFilePath).wait() && _this.$fs.exists(_this.projectPodFilePath).wait()) {
                var pluginPodFileContent = _this.$fs.readText(pluginPodFilePath).wait();
                var projectPodFileContent = _this.$fs.readText(_this.projectPodFilePath).wait();
                var contentToRemove = _this.buildPodfileContent(pluginPodFilePath, pluginPodFileContent);
                projectPodFileContent = helpers.stringReplaceAll(projectPodFileContent, contentToRemove, "");
                if (projectPodFileContent.trim() === "use_frameworks!" + os.EOL + os.EOL + "target \"" + _this.$projectData.projectName + "\" do" + os.EOL + os.EOL + "end") {
                    _this.$fs.deleteFile(_this.projectPodFilePath).wait();
                }
                else {
                    _this.$fs.writeFile(_this.projectPodFilePath, projectPodFileContent).wait();
                }
            }
        }).future()();
    };
    IOSProjectService.prototype.buildPodfileContent = function (pluginPodFilePath, pluginPodFileContent) {
        return "# Begin Podfile - " + pluginPodFilePath + " " + os.EOL + " " + pluginPodFileContent + " " + os.EOL + " # End Podfile " + os.EOL;
    };
    IOSProjectService.prototype.generateModulemap = function (headersFolderPath, libraryName) {
        var _this = this;
        var headersFilter = function (fileName, containingFolderPath) { return (path.extname(fileName) === ".h" && _this.$fs.getFsStats(path.join(containingFolderPath, fileName)).wait().isFile()); };
        var headersFolderContents = this.$fs.readDirectory(headersFolderPath).wait();
        var headers = _(headersFolderContents).filter(function (item) { return headersFilter(item, headersFolderPath); }).value();
        if (!headers.length) {
            this.$fs.deleteFile(path.join(headersFolderPath, "module.modulemap")).wait();
            return;
        }
        headers = _.map(headers, function (value) { return ("header \"" + value + "\""); });
        var modulemap = "module " + libraryName + " { explicit module " + libraryName + " { " + headers.join(" ") + " } }";
        this.$fs.writeFile(path.join(headersFolderPath, "module.modulemap"), modulemap).wait();
    };
    IOSProjectService.prototype.mergeXcconfigFiles = function (pluginFile, projectFile) {
        var _this = this;
        return (function () {
            if (!_this.$fs.exists(projectFile).wait()) {
                _this.$fs.writeFile(projectFile, "").wait();
            }
            _this.checkIfXcodeprojIsRequired().wait();
            var escapedProjectFile = projectFile.replace(/'/g, "\\'"), escapedPluginFile = pluginFile.replace(/'/g, "\\'"), mergeScript = "require 'xcodeproj'; Xcodeproj::Config.new('" + escapedProjectFile + "').merge(Xcodeproj::Config.new('" + escapedPluginFile + "')).save_as(Pathname.new('" + escapedProjectFile + "'))";
            _this.$childProcess.exec("ruby -e \"" + mergeScript + "\"").wait();
        }).future()();
    };
    IOSProjectService.prototype.mergeProjectXcconfigFiles = function () {
        var _this = this;
        return (function () {
            _this.$fs.deleteFile(_this.$options.release ? _this.pluginsReleaseXcconfigFilePath : _this.pluginsDebugXcconfigFilePath).wait();
            var allPlugins = _this.$injector.resolve("pluginsService").getAllInstalledPlugins().wait();
            for (var _i = 0, allPlugins_2 = allPlugins; _i < allPlugins_2.length; _i++) {
                var plugin = allPlugins_2[_i];
                var pluginPlatformsFolderPath = plugin.pluginPlatformsFolderPath(IOSProjectService.IOS_PLATFORM_NAME);
                var pluginXcconfigFilePath = path.join(pluginPlatformsFolderPath, "build.xcconfig");
                if (_this.$fs.exists(pluginXcconfigFilePath).wait()) {
                    _this.mergeXcconfigFiles(pluginXcconfigFilePath, _this.$options.release ? _this.pluginsReleaseXcconfigFilePath : _this.pluginsDebugXcconfigFilePath).wait();
                }
            }
            var appResourcesXcconfigPath = path.join(_this.$projectData.projectDir, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME, _this.platformData.normalizedPlatformName, "build.xcconfig");
            if (_this.$fs.exists(appResourcesXcconfigPath).wait()) {
                _this.mergeXcconfigFiles(appResourcesXcconfigPath, _this.$options.release ? _this.pluginsReleaseXcconfigFilePath : _this.pluginsDebugXcconfigFilePath).wait();
            }
            var podFilesRootDirName = path.join("Pods", "Target Support Files", "Pods-" + _this.$projectData.projectName);
            var podFolder = path.join(_this.platformData.projectRoot, podFilesRootDirName);
            if (_this.$fs.exists(podFolder).wait()) {
                if (_this.$options.release) {
                    _this.mergeXcconfigFiles(path.join(_this.platformData.projectRoot, podFilesRootDirName, "Pods-" + _this.$projectData.projectName + ".release.xcconfig"), _this.pluginsReleaseXcconfigFilePath).wait();
                }
                else {
                    _this.mergeXcconfigFiles(path.join(_this.platformData.projectRoot, podFilesRootDirName, "Pods-" + _this.$projectData.projectName + ".debug.xcconfig"), _this.pluginsDebugXcconfigFilePath).wait();
                }
            }
        }).future()();
    };
    IOSProjectService.prototype.checkIfXcodeprojIsRequired = function () {
        var _this = this;
        return (function () {
            var xcprojInfo = _this.$xcprojService.getXcprojInfo().wait();
            if (xcprojInfo.shouldUseXcproj && !xcprojInfo.xcprojAvailable) {
                var errorMessage = "You are using CocoaPods version " + xcprojInfo.cocoapodVer + " which does not support Xcode " + xcprojInfo.xcodeVersion.major + "." + xcprojInfo.xcodeVersion.minor + " yet." + os_1.EOL + os_1.EOL + "You can update your cocoapods by running $sudo gem install cocoapods from a terminal." + os_1.EOL + os_1.EOL + "In order for the NativeScript CLI to be able to work correctly with this setup you need to install xcproj command line tool and add it to your PATH. Xcproj can be installed with homebrew by running $ brew install xcproj from the terminal";
                _this.$errors.failWithoutHelp(errorMessage);
                return true;
            }
        }).future()();
    };
    IOSProjectService.prototype.getXcodeVersion = function () {
        var xcodeBuildVersion = "";
        try {
            xcodeBuildVersion = this.$childProcess.exec("xcodebuild -version | head -n 1 | sed -e 's/Xcode //'").wait();
        }
        catch (error) {
            this.$errors.fail("xcodebuild execution failed. Make sure that you have latest Xcode and tools installed.");
        }
        var splitedXcodeBuildVersion = xcodeBuildVersion.split(".");
        if (splitedXcodeBuildVersion.length === 3) {
            xcodeBuildVersion = splitedXcodeBuildVersion[0] + "." + splitedXcodeBuildVersion[1];
        }
        return xcodeBuildVersion;
    };
    IOSProjectService.prototype.getDevelopmentTeams = function () {
        var dir = path.join(process.env.HOME, "Library/MobileDevice/Provisioning Profiles/");
        var files = this.$fs.readDirectory(dir).wait();
        var teamIds = {};
        for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
            var file = files_1[_i];
            var filePath = path.join(dir, file);
            var data = this.$fs.readText(filePath, "utf8").wait();
            var teamId = this.getProvisioningProfileValue("TeamIdentifier", data);
            var teamName = this.getProvisioningProfileValue("TeamName", data);
            if (teamId) {
                teamIds[teamId] = teamName;
            }
        }
        var teamIdsArray = new Array();
        for (var teamId in teamIds) {
            teamIdsArray.push({ id: teamId, name: teamIds[teamId] });
        }
        return teamIdsArray;
    };
    IOSProjectService.prototype.getProvisioningProfileValue = function (name, text) {
        var findStr = "<key>" + name + "</key>";
        var index = text.indexOf(findStr);
        if (index > 0) {
            index = text.indexOf("<string>", index + findStr.length);
            if (index > 0) {
                index += "<string>".length;
                var endIndex = text.indexOf("</string>", index);
                var result = text.substring(index, endIndex);
                return result;
            }
        }
        return null;
    };
    IOSProjectService.prototype.readTeamId = function () {
        var xcconfigFile = path.join(this.$projectData.appResourcesDirectoryPath, this.platformData.normalizedPlatformName, "build.xcconfig");
        if (this.$fs.exists(xcconfigFile).wait()) {
            var text = this.$fs.readText(xcconfigFile).wait();
            var teamId_1;
            text.split(/\r?\n/).forEach(function (line) {
                line = line.replace(/\/(\/)[^\n]*$/, "");
                if (line.indexOf("DEVELOPMENT_TEAM") >= 0) {
                    teamId_1 = line.split("=")[1].trim();
                    if (teamId_1[teamId_1.length - 1] === ';') {
                        teamId_1 = teamId_1.slice(0, -1);
                    }
                }
            });
            if (teamId_1) {
                return teamId_1;
            }
        }
        var fileName = path.join(this.platformData.projectRoot, "teamid");
        if (this.$fs.exists(fileName).wait()) {
            return this.$fs.readText(fileName).wait();
        }
        return null;
    };
    IOSProjectService.prototype.getDevelopmentTeam = function () {
        var teamId;
        if (this.$options.teamId) {
            teamId = this.$options.teamId;
        }
        else {
            teamId = this.readTeamId();
        }
        if (!teamId) {
            var teams = this.getDevelopmentTeams();
            this.$logger.warn("Xcode 8 requires a team id to be specified when building for device.");
            this.$logger.warn("You can specify the team id by setting the DEVELOPMENT_TEAM setting in build.xcconfig file located in App_Resources folder of your app, or by using the --teamId option when calling run, debug or livesync commnads.");
            if (teams.length === 1) {
                teamId = teams[0].id;
                this.$logger.warn("Found and using the following development team installed on your system: " + teams[0].name + " (" + teams[0].id + ")");
            }
            else if (teams.length > 0) {
                var choices = [];
                for (var _i = 0, teams_1 = teams; _i < teams_1.length; _i++) {
                    var team = teams_1[_i];
                    choices.push(team.name + " (" + team.id + ")");
                }
                var choice = this.$prompter.promptForChoice('Found multiple development teams, select one:', choices).wait();
                teamId = teams[choices.indexOf(choice)].id;
                var choicesPersist = [
                    "Yes, set the DEVELOPMENT_TEAM setting in build.xcconfig file.",
                    "Yes, persist the team id in platforms folder.",
                    "No, don't persist this setting."
                ];
                var choicePersist = this.$prompter.promptForChoice("Do you want to make teamId: " + teamId + " a persistent choice for your app?", choicesPersist).wait();
                switch (choicesPersist.indexOf(choicePersist)) {
                    case 0:
                        var xcconfigFile = path.join(this.$projectData.appResourcesDirectoryPath, this.platformData.normalizedPlatformName, "build.xcconfig");
                        this.$fs.appendFile(xcconfigFile, "\nDEVELOPMENT_TEAM = " + teamId + "\n").wait();
                        break;
                    case 1:
                        this.$fs.writeFile(path.join(this.platformData.projectRoot, "teamid"), teamId);
                        break;
                    default:
                        break;
                }
            }
        }
        return teamId;
    };
    IOSProjectService.XCODE_PROJECT_EXT_NAME = ".xcodeproj";
    IOSProjectService.XCODE_SCHEME_EXT_NAME = ".xcscheme";
    IOSProjectService.XCODEBUILD_MIN_VERSION = "6.0";
    IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER = "__PROJECT_NAME__";
    IOSProjectService.IOS_PLATFORM_NAME = "ios";
    IOSProjectService.PODFILE_POST_INSTALL_SECTION_NAME = "post_install";
    return IOSProjectService;
}(projectServiceBaseLib.PlatformProjectServiceBase));
exports.IOSProjectService = IOSProjectService;
$injector.register("iOSProjectService", IOSProjectService);
