1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3    return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6const config_plugins_1 = require("@expo/config-plugins");
7const fs_1 = __importDefault(require("fs"));
8const path_1 = __importDefault(require("path"));
9const DEV_MENU_ANDROID_IMPORT = 'expo.modules.devmenu.react.DevMenuAwareReactActivity';
10const DEV_MENU_ACTIVITY_CLASS = 'public class MainActivity extends DevMenuAwareReactActivity {';
11const DEV_MENU_POD_IMPORT = "pod 'expo-dev-menu', path: '../node_modules/expo-dev-menu', :configurations => :debug";
12const DEV_MENU_IOS_IMPORT = `
13#if defined(EX_DEV_MENU_ENABLED)
14@import EXDevMenu;
15#endif`;
16const DEV_MENU_IOS_INIT = `
17#if defined(EX_DEV_MENU_ENABLED)
18  [DevMenuManager configureWithBridge:bridge];
19#endif`;
20async function readFileAsync(path) {
21    return fs_1.default.promises.readFile(path, 'utf8');
22}
23async function saveFileAsync(path, content) {
24    return fs_1.default.promises.writeFile(path, content, 'utf8');
25}
26function addJavaImports(javaSource, javaImports) {
27    const lines = javaSource.split('\n');
28    const lineIndexWithPackageDeclaration = lines.findIndex(line => line.match(/^package .*;$/));
29    for (const javaImport of javaImports) {
30        if (!javaSource.includes(javaImport)) {
31            const importStatement = `import ${javaImport};`;
32            lines.splice(lineIndexWithPackageDeclaration + 1, 0, importStatement);
33        }
34    }
35    return lines.join('\n');
36}
37function addLines(content, find, offset, toAdd) {
38    const lines = content.split('\n');
39    let lineIndex = lines.findIndex(line => line.match(find));
40    for (const newLine of toAdd) {
41        if (!content.includes(newLine)) {
42            lines.splice(lineIndex + offset, 0, newLine);
43            lineIndex++;
44        }
45    }
46    return lines.join('\n');
47}
48async function editPodfile(config, action) {
49    const podfilePath = path_1.default.join(config.modRequest.platformProjectRoot, 'Podfile');
50    try {
51        const podfile = action(await readFileAsync(podfilePath));
52        return await saveFileAsync(podfilePath, podfile);
53    }
54    catch (e) {
55        config_plugins_1.WarningAggregator.addWarningIOS('ios-devMenu', `Couldn't modified AppDelegate.m - ${e}.`);
56    }
57}
58async function editAppDelegate(config, action) {
59    const appDelegatePath = path_1.default.join(config.modRequest.platformProjectRoot, config.modRequest.projectName, 'AppDelegate.m');
60    try {
61        const appDelegate = action(await readFileAsync(appDelegatePath));
62        return await saveFileAsync(appDelegatePath, appDelegate);
63    }
64    catch (e) {
65        config_plugins_1.WarningAggregator.addWarningIOS('ios-devMenu', `Couldn't modified AppDelegate.m - ${e}.`);
66    }
67}
68const withDevMenuActivity = config => {
69    return config_plugins_1.withMainActivity(config, config => {
70        if (config.modResults.language === 'java') {
71            let content = config.modResults.contents;
72            content = addJavaImports(content, [DEV_MENU_ANDROID_IMPORT]);
73            content = content.replace('public class MainActivity extends ReactActivity {', DEV_MENU_ACTIVITY_CLASS);
74            config.modResults.contents = content;
75        }
76        else {
77            config_plugins_1.WarningAggregator.addWarningAndroid('android-devMenu', `Cannot automatically configure MainActivity if it's not java`);
78        }
79        return config;
80    });
81};
82const withDevMenuPodfile = config => {
83    return config_plugins_1.withDangerousMod(config, [
84        'ios',
85        async (config) => {
86            await editPodfile(config, podfile => {
87                podfile = podfile.replace("platform :ios, '10.0'", "platform :ios, '11.0'");
88                // Match both variations of Ruby config:
89                // unknown: pod 'expo-dev-menu', path: '../node_modules/expo-dev-menu', :configurations => :debug
90                // Rubocop: pod 'expo-dev-menu', path: '../node_modules/expo-dev-menu', configurations: :debug
91                if (!podfile.match(/pod ['"]expo-dev-menu['"],\s?path: ['"]\.\.\/node_modules\/expo-dev-menu['"],\s?:?configurations:?\s(?:=>\s)?:debug/)) {
92                    podfile = addLines(podfile, 'use_react_native', 0, [`  ${DEV_MENU_POD_IMPORT}`]);
93                }
94                return podfile;
95            });
96            return config;
97        },
98    ]);
99};
100const withDevMenuAppDelegate = config => {
101    return config_plugins_1.withDangerousMod(config, [
102        'ios',
103        async (config) => {
104            await editAppDelegate(config, appDelegate => {
105                if (!appDelegate.includes(DEV_MENU_IOS_IMPORT)) {
106                    const lines = appDelegate.split('\n');
107                    lines.splice(1, 0, DEV_MENU_IOS_IMPORT);
108                    appDelegate = lines.join('\n');
109                }
110                if (!appDelegate.includes(DEV_MENU_IOS_INIT)) {
111                    const lines = appDelegate.split('\n');
112                    const initializeReactNativeAppIndex = lines.findIndex(line => line.includes('- (RCTBridge *)initializeReactNativeApp'));
113                    const rootViewControllerIndex = lines.findIndex((line, index) => initializeReactNativeAppIndex < index && line.includes('rootViewController'));
114                    lines.splice(rootViewControllerIndex - 1, 0, DEV_MENU_IOS_INIT);
115                    appDelegate = lines.join('\n');
116                }
117                return appDelegate;
118            });
119            return config;
120        },
121    ]);
122};
123const withDevMenu = (config) => {
124    config = withDevMenuActivity(config);
125    config = withDevMenuPodfile(config);
126    config = withDevMenuAppDelegate(config);
127    return config;
128};
129exports.default = withDevMenu;
130