const rootPath = '../../../';
const stripJsonComments = require('strip-json-comments');
const xcode = require('nativescript-dev-xcode'), path = require('path'), fs = require('fs'), fse = require('fs-extra'), projectPath = path.join(rootPath, 'ios/App/App.xcodeproj/project.pbxproj'), appDelegatePath = path.join(rootPath, 'ios/App/App/AppDelegate.swift');
// console.log('projectPath:', path.resolve(projectPath));
if (fse.existsSync(projectPath)) {
    // check if already embedded
    const appDelegateContent = fs.readFileSync(appDelegatePath, { encoding: 'UTF-8' });
    if (appDelegateContent && appDelegateContent.indexOf('TNSRuntime.init') === -1) {
        console.log('Capacitor detected, adding NativeScript 🚀');
        // update delegate
        console.log("Updating AppDelegate from:");
        console.log(path.resolve(appDelegatePath));
        const appDelegateContent = fs.readFileSync(appDelegatePath, { encoding: 'UTF-8' });
        if (appDelegateContent) {
            const winVar = 'window: UIWindow?';
            const uiWinIndex = appDelegateContent.indexOf(winVar);
            const modifyPart1 = appDelegateContent.split('');
            // add runtime var
            modifyPart1.splice(uiWinIndex + winVar.length + 1, 0, `    var runtime: TNSRuntime?\n`);
            let updatedDelegate = modifyPart1.join('');
            const didFinishLaunch = `UIApplication.LaunchOptionsKey: Any]?) -> Bool {`;
            const didFinishLaunchIndex = updatedDelegate.indexOf(didFinishLaunch);
            const modifyPart2 = updatedDelegate.split('');
            // add runtime init
            modifyPart2.splice(didFinishLaunchIndex + didFinishLaunch.length + 1, 0, `        // NativeScript init\n        let pointer = runtimeMeta()\n        
      TNSRuntime.initializeMetadata(pointer)\n        
      self.runtime = TNSRuntime.init(applicationPath: Bundle.main.bundlePath)\n        
      self.runtime?.executeModule("../public/nativescript.js")\n\n`);
            updatedDelegate = modifyPart2.join('');
            // save updates
            fs.writeFileSync(appDelegatePath, updatedDelegate);
            console.log('UPDATED:', path.resolve(appDelegatePath));
        }
        // -- NOTE: All Angular specific below
        // This uses "js" instead of typescript due to necessity of using custom webpack config for separate bundles
        // we could auto add this plugin as referenced here for angular projects:
        // https://github.com/angular/angular-cli/issues/17913#issuecomment-642918019
        // and autoconfigure based on that but this works as well
        fse.ensureDirSync(path.join(rootPath, 'src/nativescript'));
        const nsBridgePath = path.join(rootPath, 'src/nativescript/nativescript-bridge.js');
        // add a file where users can code their own custom {N}
        const nsHelpersPath = path.join(rootPath, 'src/nativescript/index.js');
        if (!fs.existsSync(nsBridgePath)) {
            fs.copyFileSync('./dist/esm/nativescript-bridge.js', nsBridgePath);
        }
        if (!fs.existsSync(nsHelpersPath)) {
            fs.copyFileSync('./dist/esm/nativescript-sample.js', nsHelpersPath);
        }
        const refPath = path.join(rootPath, 'references.d.ts');
        if (!fs.existsSync(refPath)) {
            fs.copyFileSync('./references.d.ts', refPath);
        }
        // Add NativeScript typings references
        const tsConfigAppPath = path.join(rootPath, 'tsconfig.app.json');
        const tsConfigAppContent = fs.readFileSync(tsConfigAppPath, { encoding: 'UTF-8' });
        if (tsConfigAppContent) {
            const tsConfigAppJson = JSON.parse(stripJsonComments(tsConfigAppContent));
            if (tsConfigAppJson && tsConfigAppJson.files && !tsConfigAppJson.files.includes('references.d.ts')) {
                tsConfigAppJson.files.unshift('references.d.ts');
                fs.writeFileSync(tsConfigAppPath, `${JSON.stringify(tsConfigAppJson, null, 2)}\n`);
            }
        }
        // Angular specific integration sample here:
        // TODO: detect project type to autoconfigure
        // If angular.json not found, fallback to workspace.json for Nx and find app to attach to
        // may need prompt cli to allow user to specify the project/app name
        const angularJsonPath = path.join(rootPath, 'angular.json');
        // console.log('angularJsonPath:', angularJsonPath)
        const angularJsonContent = fs.readFileSync(angularJsonPath, { encoding: 'UTF-8' });
        // console.log('angularJsonContent:', angularJsonContent)
        if (angularJsonContent) {
            const angularJson = JSON.parse(stripJsonComments(angularJsonContent));
            if (angularJson && angularJson.projects) {
                // Ionic standalone projects (outside Nx) use assumed 'app' project name
                if (angularJson.projects.app) {
                    let targetApp = angularJson.projects.app.architect;
                    let architect = 'architect';
                    if (!targetApp) {
                        // Nx
                        architect = 'targets';
                        targetApp = angularJson.projects.app[architect];
                    }
                    if (targetApp && targetApp.build && targetApp.build.options) {
                        if (!targetApp.build.options.scripts) {
                            targetApp.build.options.scripts = [];
                        }
                        let hasBridge = false;
                        let hasHelpers = false;
                        const nsBridge = 'src/nativescript/nativescript-bridge.js';
                        const nsSampleHelpers = 'src/nativescript/index.js';
                        for (const script of targetApp.build.options.scripts) {
                            if (typeof script !== 'string' && typeof script === 'object') {
                                if (script.input === nsBridge) {
                                    hasBridge = true;
                                }
                                if (script.input === nsSampleHelpers) {
                                    hasHelpers = true;
                                }
                            }
                        }
                        if (!hasBridge) {
                            targetApp.build.options.scripts.push({
                                input: "src/nativescript/nativescript-bridge.js",
                                inject: false,
                                bundleName: "nativescript-bridge"
                            });
                        }
                        if (!hasHelpers) {
                            targetApp.build.options.scripts.push({
                                input: "src/nativescript/index.js",
                                inject: false,
                                bundleName: "nativescript"
                            });
                        }
                        angularJson.projects.app[architect] = targetApp;
                        fs.writeFileSync(angularJsonPath, `${JSON.stringify(angularJson, null, 2)}\n`);
                    }
                }
            }
        }
        // XCode embedding
        const xcProj = xcode.project(projectPath);
        // console.log('rootPath:', path.resolve(rootPath));
        // console.log("Looking for xcode project at ", path.resolve(path.join(rootPath, 'ios/App/')));
        xcProj.parse(function (err) {
            //copy frameworks
            fse.copySync('./embed/NSFrameworks/TNSWidgets.framework', path.join(rootPath, 'ios/App/TNSWidgets.framework'));
            fse.copySync('./embed/NSFrameworks/NativeScript.framework', path.join(rootPath, 'ios/App/NativeScript.framework'));
            fse.copySync('./embed/internal', path.join(rootPath, 'ios/App/internal'));
            fse.copySync('./embed/NativeScript', path.join(rootPath, 'ios/App/NativeScript'));
            //  add runtime files
            const group = getRootGroup("NativeScript", path.join(rootPath, 'ios/App/NativeScript'));
            // console.log(group)
            xcProj.addPbxGroup(group.files, group.name, group.path, null, {
                isMain: true,
                filesRelativeToProject: true,
            });
            let hasPreBuild = false;
            let hasPreLink = false;
            let hasPostBuild = false;
            let hasCopyNSApp = false;
            let hasEmbedFrameworks = false;
            //  check for each build phase
            let nativeTargetSection = xcProj.pbxNativeTargetSection();
            for (const key in nativeTargetSection) {
                if (Object.hasOwnProperty.call(nativeTargetSection, key)) {
                    const el = nativeTargetSection[key];
                    if (el.buildPhases) {
                        let newBuildPhases = el.buildPhases;
                        for (let i = 0; i < el.buildPhases.length; i++) {
                            const phase = el.buildPhases[i];
                            if (phase.comment === "PreBuild") {
                                hasPreBuild = true;
                            }
                            if (phase.comment === "PreLink") {
                                hasPreLink = true;
                            }
                            if (phase.comment === "Copy NSApp") {
                                hasCopyNSApp = true;
                            }
                            if (phase.comment === "PostBuild") {
                                hasPostBuild = true;
                            }
                            if (phase.comment === "Embed Frameworks") {
                                hasEmbedFrameworks = true;
                            }
                        }
                        el.buildPhases = newBuildPhases;
                    }
                }
            }
            // add non-existing build phases
            if (!hasPreBuild) {
                addPreBuild(xcProj);
            }
            if (!hasPreLink) {
                addPreLink(xcProj);
            }
            // will be needed if we want to copy an entire NS app
            // if (!hasCopyNSApp) {
            //     addCopyNSApp(xcProj);
            // }
            // if (!hasPostBuild) {
            //     addPostBuild(xcProj);
            // }
            if (!hasEmbedFrameworks) {
                addEmbedFrameworks(xcProj);
            }
            //  sort build phases
            for (const key in nativeTargetSection) {
                if (Object.hasOwnProperty.call(nativeTargetSection, key)) {
                    const el = nativeTargetSection[key];
                    if (el.buildPhases) {
                        let newBuildPhases = new Array(8); // TODO: dont forget to update this
                        for (let i = 0; i < el.buildPhases.length; i++) {
                            const phase = el.buildPhases[i];
                            if (phase.comment === "[CP] Check Pods Manifest.lock") {
                                newBuildPhases[0] = phase;
                            }
                            if (phase.comment === "PreBuild") {
                                newBuildPhases[1] = phase;
                            }
                            if (phase.comment === "Sources") {
                                newBuildPhases[2] = phase;
                            }
                            if (phase.comment === "PreLink") {
                                newBuildPhases[3] = phase;
                            }
                            if (phase.comment === "Frameworks") {
                                newBuildPhases[4] = phase;
                            }
                            if (phase.comment === "Resources") {
                                newBuildPhases[5] = phase;
                            }
                            if (phase.comment === "[CP] Embed Pods Frameworks") {
                                newBuildPhases[6] = phase;
                            }
                            if (phase.comment === "Embed Frameworks") {
                                newBuildPhases[7] = phase;
                            }
                            // if (phase.comment === "Copy NSApp") {
                            //     newBuildPhases[8] = phase;
                            // }
                            // if (phase.comment === "PostBuild") {
                            //     newBuildPhases[9] = phase;
                            // }
                        }
                        el.buildPhases = newBuildPhases;
                    }
                }
            }
            // add frameworks
            const nsframeworkRelativePath = "NativeScript.framework";
            xcProj.addFramework(nsframeworkRelativePath, { embed: true, sign: true, customFramework: true, target: xcProj.getFirstTarget().uuid });
            const tnswidgetsRelativePath = "TNSWidgets.framework";
            xcProj.addFramework(tnswidgetsRelativePath, { embed: true, sign: true, customFramework: true, target: xcProj.getFirstTarget().uuid });
            xcProj.addToHeaderSearchPaths("$(SRCROOT)/NativeScript");
            xcProj.addToBuildSettings('SWIFT_OBJC_BRIDGING_HEADER', "\"$(SRCROOT)/NativeScript/App-Bridging-Header.h\"");
            xcProj.addToBuildSettings('OTHER_LDFLAGS', "(\r\n\t\t\t\t\t\"$(inherited)\",\r\n\t\t\t\t\t\"-framework\",\r\n\t\t\t\t\t\"\\\"Capacitor\\\"\",\r\n\t\t\t\t\t\"-framework\",\r\n\t\t\t\t\t\"\\\"Cordova\\\"\",\r\n\t\t\t\t\t\"-framework\",\r\n\t\t\t\t\t\"\\\"WebKit\\\"\",\r\n\t\t\t\t\t\"$(inherited)\",\r\n\t\t\t\t\t\"-ObjC\",\r\n\t\t\t\t\t\"-sectcreate\",\r\n\t\t\t\t\t__DATA,\r\n\t\t\t\t\t__TNSMetadata,\r\n\t\t\t\t\t\"\\\"$(CONFIGURATION_BUILD_DIR)\/metadata-$(CURRENT_ARCH).bin\\\"\",\r\n\t\t\t\t\t\"-framework\",\r\n\t\t\t\t\tNativeScript,\r\n\t\t\t\t\t\"-F\\\"$(SRCROOT)\/internal\\\"\",\r\n\t\t\t\t\t\"-licucore\",\r\n\t\t\t\t\t\"-lz\",\r\n\t\t\t\t\t\"-lc++\",\r\n\t\t\t\t\t\"-framework\",\r\n\t\t\t\t\tFoundation,\r\n\t\t\t\t\t\"-framework\",\r\n\t\t\t\t\tUIKit,\r\n\t\t\t\t\t\"-framework\",\r\n\t\t\t\t\tCoreGraphics,\r\n\t\t\t\t\t\"-framework\",\r\n\t\t\t\t\tMobileCoreServices,\r\n\t\t\t\t\t\"-framework\",\r\n\t\t\t\t\tSecurity,\r\n\t\t\t\t)");
            xcProj.addToBuildSettings('LD', "\"$SRCROOT/internal/nsld.sh\"");
            xcProj.addToBuildSettings('LDPLUSPLUS', "\"$SRCROOT/internal/nsld.sh\"");
            fs.writeFileSync(projectPath, xcProj.writeSync());
        });
        function addPreBuild(proj) {
            proj.addBuildPhase([], 'PBXShellScriptBuildPhase', 'PreBuild', null, {
                shellPath: '/bin/sh',
                shellScript: '"${SRCROOT}/internal/nativescript-pre-build"'
            });
        }
        function addPreLink(proj) {
            proj.addBuildPhase([], 'PBXShellScriptBuildPhase', 'PreLink', null, {
                shellPath: '/bin/sh',
                shellScript: '"${SRCROOT}/internal/nativescript-pre-link"'
            });
        }
        function addPostBuild(proj) {
            proj.addBuildPhase([], 'PBXShellScriptBuildPhase', 'PostBuild', null, {
                shellPath: '/bin/sh',
                shellScript: '"${SRCROOT}/internal/nativescript-post-build"'
            });
        }
        function addCopyNSApp(proj) {
            proj.addBuildPhase(['../nsappfolder'], 'PBXCopyFilesBuildPhase', 'Copy NSApp', null, null);
        }
        function addEmbedFrameworks(proj) {
            proj.addBuildPhase([], 'PBXCopyFilesBuildPhase', 'Embed Frameworks', null, 'frameworks');
        }
        function getRootGroup(name, rootPath) {
            const filePathsArr = [];
            const rootGroup = {
                name: name,
                files: filePathsArr,
                path: rootPath,
            };
            if (fs.existsSync(rootPath)) {
                fs.readdirSync(rootPath).forEach((fileName) => {
                    const filePath = path.join(rootGroup.path, fileName);
                    filePathsArr.push(filePath);
                });
            }
            return rootGroup;
        }
    }
}
else {
    console.log('@nativescript/capacitor installed.');
}
//# sourceMappingURL=postinstall.js.map