const rootPath = '../../../';

const xcode = require('nativescript-dev-xcode'),
    path = require('path'),
    fs = require('fs'),
    projectPath = path.join(rootPath, 'ios/App/App.xcodeproj/project.pbxproj'),
    xcProj = xcode.project(projectPath),
    fse = require('fs-extra');


console.log("Looking for xcode project at ", path.resolve(path.join(rootPath, 'ios/App/')));

xcProj.parse(function (err) {

    //copy frameworks
    fse.copySync('./NSFrameworks/TNSWidgets.framework', path.join(rootPath, 'ios/App/TNSWidgets.framework'));
    fse.copySync('./NSFrameworks/NativeScript.framework', path.join(rootPath, 'ios/App/NativeScript.framework'));
    fse.copySync('./internal', path.join(rootPath, 'ios/App/internal'));
    fse.copySync('./NativeScript', path.join(rootPath, 'ios/App/NativeScript'));

    console.log("Deleting AppDelegate from:");
    console.log(path.resolve(path.join(rootPath, 'ios/App/App/AppDelegate.swift')));
    fs.unlinkSync(path.join(rootPath, 'ios/App/App/AppDelegate.swift'));

    // replace appdelegate
    fs.copyFileSync('./AppDelegate.swift', path.join(rootPath, 'ios/App/App/AppDelegate.swift'));

    // //copy bridging header
    // fs.copyFileSync('./NativeScript/App-Bridging-Header.h', path.join(rootPath, 'ios/App/App'));

    // add ns app
    fs.copyFileSync('./hellons.js', path.join(rootPath, 'ios/App/App/hellons.js'));

    //  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) { //needed for embed&sign
    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;
}