"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.startAsync = exports.printServerInfo = void 0;

function _xdl() {
  const data = require("@expo/xdl");

  _xdl = function () {
    return data;
  };

  return data;
}

function _chalk() {
  const data = _interopRequireDefault(require("chalk"));

  _chalk = function () {
    return data;
  };

  return data;
}

function _trimStart() {
  const data = _interopRequireDefault(require("lodash/trimStart"));

  _trimStart = function () {
    return data;
  };

  return data;
}

function _openBrowser() {
  const data = _interopRequireDefault(require("react-dev-utils/openBrowser"));

  _openBrowser = function () {
    return data;
  };

  return data;
}

function _readline() {
  const data = _interopRequireDefault(require("readline"));

  _readline = function () {
    return data;
  };

  return data;
}

function _wordwrap() {
  const data = _interopRequireDefault(require("wordwrap"));

  _wordwrap = function () {
    return data;
  };

  return data;
}

function _accounts() {
  const data = require("../../accounts");

  _accounts = function () {
    return data;
  };

  return data;
}

function _log() {
  const data = _interopRequireDefault(require("../../log"));

  _log = function () {
    return data;
  };

  return data;
}

function _urlOpts() {
  const data = _interopRequireDefault(require("../../urlOpts"));

  _urlOpts = function () {
    return data;
  };

  return data;
}

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const CTRL_C = '\u0003';
const CTRL_D = '\u0004';
const CTRL_L = '\u000C';

const {
  bold: b,
  italic: i,
  underline: u
} = _chalk().default;

const clearConsole = () => {
  process.stdout.write(process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H');
};

const printHelp = () => {
  const PLATFORM_TAG = _xdl().ProjectUtils.getPlatformTag('Expo');

  _log().default.newLine();

  _log().default.nested(`${PLATFORM_TAG} Press ${b('?')} to show a list of all available commands.`);
};

const printUsage = async (projectDir, options = {}) => {
  const {
    dev
  } = await _xdl().ProjectSettings.readAsync(projectDir);
  const {
    exp
  } = await _xdl().ProjectUtils.readConfigJsonAsync(projectDir);
  const openDevToolsAtStartup = await _xdl().UserSettings.getAsync('openDevToolsAtStartup', true);
  const username = await _xdl().UserManager.getCurrentUsernameAsync();
  const devMode = dev ? 'development' : 'production';
  const androidInfo = `${b`a`} to run on ${u`A`}ndroid device/emulator`;
  const iosInfo = process.platform === 'darwin' ? `${b`i`} to run on ${u`i`}OS simulator` : '';
  const webInfo = exp.platforms.includes('web') ? `${b`w`} to run on ${u`w`}eb` : '';
  const platformInfo = [androidInfo, iosInfo, webInfo].filter(Boolean).join(', or ');

  _log().default.nested(`
 \u203A Press ${platformInfo}.
 \u203A Press ${b`c`} to show info on ${u`c`}onnecting new devices.
 \u203A Press ${b`d`} to open DevTools in the default web browser.
 \u203A Press ${b`shift-d`} to ${openDevToolsAtStartup ? 'disable' : 'enable'} automatically opening ${u`D`}evTools at startup.${options.webOnly ? '' : `\n \u203A Press ${b`e`} to send an app link with ${u`e`}mail.`}
 \u203A Press ${b`p`} to toggle ${u`p`}roduction mode. (current mode: ${i(devMode)})
 \u203A Press ${b`r`} to ${u`r`}estart bundler, or ${b`shift-r`} to restart and clear cache.
 \u203A Press ${b`s`} to ${u`s`}ign ${username ? `out. (Signed in as ${i('@' + username)}.)` : 'in.'}
`);
};

const printServerInfo = async (projectDir, options = {}) => {
  if (options.webOnly) {
    _xdl().Webpack.printConnectionInstructions(projectDir);

    printHelp();
    return;
  }

  const url = await _xdl().UrlUtils.constructManifestUrlAsync(projectDir);
  const username = await _xdl().UserManager.getCurrentUsernameAsync();

  _log().default.newLine();

  _log().default.nested(`  ${u(url)}`);

  _log().default.newLine();

  _urlOpts().default.printQRCode(url);

  const wrap = (0, _wordwrap().default)(2, process.stdout.columns || 80);
  const wrapItem = (0, _wordwrap().default)(4, process.stdout.columns || 80);

  const item = text => '  \u2022 ' + (0, _trimStart().default)(wrapItem(text));

  const iosInfo = process.platform === 'darwin' ? `, or ${b('i')} for iOS simulator` : '';

  _log().default.nested(wrap(u('To run the app with live reloading, choose one of:')));

  if (username) {
    _log().default.nested(item(`Sign in as ${i('@' + username)} in Expo Client on Android or iOS. Your projects will automatically appear in the "Projects" tab.`));
  }

  _log().default.nested(item(`Scan the QR code above with the Expo app (Android) or the Camera app (iOS).`));

  _log().default.nested(item(`Press ${b`a`} for Android emulator${iosInfo}.`));

  _log().default.nested(item(`Press ${b`e`} to send a link to your phone with email.`));

  if (!username) {
    _log().default.nested(item(`Press ${b`s`} to sign in and enable more options.`));
  }

  _xdl().Webpack.printConnectionInstructions(projectDir);

  printHelp();
};

exports.printServerInfo = printServerInfo;

const startAsync = async (projectDir, options) => {
  const {
    stdin
  } = process;

  const startWaitingForCommand = () => {
    stdin.setRawMode(true);
    stdin.resume();
    stdin.setEncoding('utf8');
    stdin.on('data', handleKeypress);
  };

  const stopWaitingForCommand = () => {
    stdin.removeListener('data', handleKeypress);
    stdin.setRawMode(false);
    stdin.resume();
  };

  startWaitingForCommand();
  await printServerInfo(projectDir, options);

  async function handleKeypress(key) {
    if (options.webOnly) {
      switch (key) {
        case 'a':
          clearConsole();
          (0, _log().default)('Trying to open the web project in Chrome on Android...');
          await _xdl().Android.openWebProjectAsync(projectDir);
          printHelp();
          break;

        case 'i':
          clearConsole();
          (0, _log().default)('Trying to open the web project in Safari on the iOS simulator...');
          await _xdl().Simulator.openWebProjectAsync(projectDir);
          printHelp();
          break;

        case 'e':
          (0, _log().default)(_chalk().default.red` \u203A Sending a URL is not supported in web-only mode`);
          break;
      }
    } else {
      switch (key) {
        case 'a':
          {
            clearConsole();
            (0, _log().default)('Trying to open the project on Android...');
            await _xdl().Android.openProjectAsync(projectDir);
            printHelp();
            break;
          }

        case 'i':
          {
            clearConsole();
            (0, _log().default)('Trying to open the project in iOS simulator...');
            await _xdl().Simulator.openProjectAsync(projectDir);
            printHelp();
            break;
          }

        case 'e':
          {
            stopWaitingForCommand();
            const lanAddress = await _xdl().UrlUtils.constructManifestUrlAsync(projectDir, {
              hostType: 'lan'
            });
            const defaultRecipient = await _xdl().UserSettings.getAsync('sendTo', null);

            const rl = _readline().default.createInterface({
              input: process.stdin,
              output: process.stdout
            });

            const handleKeypress = (chr, key) => {
              if (key && key.name === 'escape') {
                cleanup();
                cancel();
              }
            };

            const cleanup = () => {
              rl.close();
              process.stdin.removeListener('keypress', handleKeypress);
              startWaitingForCommand();
            };

            const cancel = async () => {
              clearConsole();
              printHelp();
            };

            clearConsole();
            process.stdin.addListener('keypress', handleKeypress);
            (0, _log().default)('Please enter your email address (press ESC to cancel) ');
            rl.question(defaultRecipient ? `[default: ${defaultRecipient}]> ` : '> ', async sendTo => {
              cleanup();

              if (!sendTo && defaultRecipient) {
                sendTo = defaultRecipient;
              }

              sendTo = sendTo && sendTo.trim();

              if (!sendTo) {
                cancel();
                return;
              }

              (0, _log().default)(`Sending ${lanAddress} to ${sendTo}...`);
              let sent = false;

              try {
                await _xdl().Exp.sendAsync(sendTo, lanAddress);
                (0, _log().default)(`Sent link successfully.`);
                sent = true;
              } catch (err) {
                (0, _log().default)(`Could not send link. ${err}`);
              }

              printHelp();

              if (sent) {
                await _xdl().UserSettings.setAsync('sendTo', sendTo);
              }
            });
            break;
          }
      }
    }

    switch (key) {
      case CTRL_C:
      case CTRL_D:
        {
          process.emit('SIGINT');
          break;
        }

      case CTRL_L:
        {
          clearConsole();
          break;
        }

      case '?':
        {
          await printUsage(projectDir, options);
          break;
        }

      case 'w':
        {
          clearConsole();
          (0, _log().default)('Attempting to open the project in a web browser...');
          await _xdl().Webpack.openAsync(projectDir);
          await printServerInfo(projectDir, options);
          break;
        }

      case 'c':
        {
          clearConsole();
          await printServerInfo(projectDir, options);
          break;
        }

      case 'd':
        {
          const {
            devToolsPort
          } = await _xdl().ProjectSettings.readPackagerInfoAsync(projectDir);
          (0, _log().default)('Opening DevTools in the browser...');
          (0, _openBrowser().default)(`http://localhost:${devToolsPort}`);
          printHelp();
          break;
        }

      case 'D':
        {
          clearConsole();
          const enabled = !(await _xdl().UserSettings.getAsync('openDevToolsAtStartup', true));
          await _xdl().UserSettings.setAsync('openDevToolsAtStartup', enabled);
          (0, _log().default)(`Automatically opening DevTools ${b(enabled ? 'enabled' : 'disabled')}.\nPress ${b`d`} to open DevTools now.`);
          printHelp();
          break;
        }

      case 'p':
        {
          clearConsole();
          const projectSettings = await _xdl().ProjectSettings.readAsync(projectDir);
          const dev = !projectSettings.dev;
          await _xdl().ProjectSettings.setAsync(projectDir, {
            dev,
            minify: !dev
          });
          (0, _log().default)(`Metro Bundler is now running in ${_chalk().default.bold(dev ? 'development' : 'production')}${_chalk().default.reset(` mode.`)}
Please reload the project in the Expo app for the change to take effect.`);
          printHelp();
          break;
        }

      case 'r':
      case 'R':
        {
          clearConsole();
          const reset = key === 'R';

          if (reset) {
            (0, _log().default)('Restarting Metro Bundler and clearing cache...');
          } else {
            (0, _log().default)('Restarting Metro Bundler...');
          }

          _xdl().Project.startAsync(projectDir, { ...options,
            reset
          });

          break;
        }

      case 's':
        {
          const authSession = await _xdl().UserManager.getSessionAsync();

          if (authSession) {
            await _xdl().UserManager.logoutAsync();
            (0, _log().default)('Signed out.');
          } else {
            stopWaitingForCommand();

            try {
              await (0, _accounts().loginOrRegisterIfLoggedOut)();
            } catch (e) {
              _log().default.error(e);
            } finally {
              startWaitingForCommand();
            }
          }

          printHelp();
          break;
        }
    }
  }
};

exports.startAsync = startAsync;
//# sourceMappingURL=../../__sourcemaps__/commands/start/TerminalUI.js.map