text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.CapacitorCommand = void 0;
  const utils_fs_1 = require("@ionic/utils-fs");
  const utils_subprocess_1 = require("@ionic/utils-subprocess");
  const path = require("path");
  const color_1 = require("../../lib/color");
  const command_1 = require("../../lib/command");
  const errors_1 = require("../../lib/errors");
  const executor_1 = require("../../lib/executor");
  const config_1 = require("../../lib/integrations/capacitor/config");
  const utils_1 = require("../../lib/integrations/capacitor/utils");
  class CapacitorCommand extends command_1.Command {
      get integration() {
          if (!this.project) {
              throw new errors_1.FatalException(`Cannot use Capacitor outside a project directory.`);
          }
          if (!this._integration) {
              this._integration = this.project.requireIntegration('capacitor');
          }
          return this._integration;
      }
      getCapacitorConfig() {
          if (!this.project) {
              throw new errors_1.FatalException(`Cannot use Capacitor outside a project directory.`);
          }
          return new config_1.CapacitorConfig(path.resolve(this.project.directory, config_1.CAPACITOR_CONFIG_FILE));
      }
      async checkCapacitor(runinfo) {
          if (!this.project) {
              throw new errors_1.FatalException(`Cannot use Capacitor outside a project directory.`);
          }
          const capacitor = this.project.getIntegration('capacitor');
          if (!capacitor) {
              await executor_1.runCommand(runinfo, ['integrations', 'enable', 'capacitor']);
          }
      }
      async preRunChecks(runinfo) {
          await this.checkCapacitor(runinfo);
      }
      async runCapacitor(argList) {
          try {
              return await this._runCapacitor(argList);
          }
          catch (e) {
              if (e instanceof utils_subprocess_1.SubprocessError) {
                  if (e.code === utils_subprocess_1.ERROR_COMMAND_NOT_FOUND) {
                      const pkg = '@capacitor/cli';
                      const requiredMsg = `The Capacitor CLI is required for Capacitor projects.`;
                      this.env.log.nl();
                      this.env.log.info(`Looks like ${color_1.input(pkg)} isn't installed in this project.\n` + requiredMsg);
                      this.env.log.nl();
                      const installed = await this.promptToInstallCapacitor();
                      if (!installed) {
                          throw new errors_1.FatalException(`${color_1.input(pkg)} is required for Capacitor projects.`);
                      }
                      return this.runCapacitor(argList);
                  }
                  if (e.code === utils_subprocess_1.ERROR_SIGNAL_EXIT) {
                      return;
                  }
              }
              throw e;
          }
      }
      async runBuild(inputs, options) {
          if (!this.project) {
              throw new errors_1.FatalException(`Cannot use Capacitor outside a project directory.`);
          }
          const conf = this.getCapacitorConfig();
          const serverConfig = conf.get('server');
          if (serverConfig && serverConfig.url) {
              this.env.log.warn(`Capacitor server URL is in use.\n` +
                  `This may result in unexpected behavior for this build, where an external server is used in the Web View instead of your app. This likely occurred because of ${color_1.input('--livereload')} usage in the past and the CLI improperly exiting without cleaning up.\n\n` +
                  `Delete the ${color_1.input('server')} key in the ${color_1.strong(config_1.CAPACITOR_CONFIG_FILE)} file if you did not intend to use an external server.`);
              this.env.log.nl();
          }
          if (options['build']) {
              try {
                  const runner = await this.project.requireBuildRunner();
                  const runnerOpts = runner.createOptionsFromCommandLine(inputs, utils_1.generateOptionsForCapacitorBuild(inputs, options));
                  await runner.run(runnerOpts);
              }
              catch (e) {
                  if (e instanceof errors_1.RunnerException) {
                      throw new errors_1.FatalException(e.message);
                  }
                  throw e;
              }
          }
      }
      async checkForPlatformInstallation(platform) {
          if (!this.project) {
              throw new errors_1.FatalException('Cannot use Capacitor outside a project directory.');
          }
          if (platform) {
              const capacitor = this.project.getIntegration('capacitor');
              if (!capacitor) {
                  throw new errors_1.FatalException('Cannot check platform installations--Capacitor not yet integrated.');
              }
              const integrationRoot = capacitor.root;
              const platformsToCheck = ['android', 'ios', 'electron'];
              const platforms = (await Promise.all(platformsToCheck.map(async (p) => [p, await utils_fs_1.pathExists(path.resolve(integrationRoot, p))])))
                  .filter(([, e]) => e)
                  .map(([p]) => p);
              if (!platforms.includes(platform)) {
                  await this._runCapacitor(['add', platform]);
              }
          }
      }
      createOptionsFromCommandLine(inputs, options) {
          const separatedArgs = options['--'];
          const verbose = !!options['verbose'];
          const conf = this.getCapacitorConfig();
          const server = conf.get('server');
          return {
              '--': separatedArgs ? separatedArgs : [],
              appId: conf.get('appId'),
              appName: conf.get('appName'),
              server: {
                  url: server === null || server === void 0 ? void 0 : server.url,
              },
              verbose,
          };
      }
      async promptToInstallCapacitor() {
          if (!this.project) {
              throw new errors_1.FatalException(`Cannot use Capacitor outside a project directory.`);
          }
          const { pkgManagerArgs } = await Promise.resolve().then(() => require('../../lib/utils/npm'));
          const pkg = '@capacitor/cli';
          const [manager, ...managerArgs] = await pkgManagerArgs(this.env.config.get('npmClient'), { pkg, command: 'install', saveDev: true });
          const confirm = await this.env.prompt({
              name: 'confirm',
              message: `Install ${color_1.input(pkg)}?`,
              type: 'confirm',
          });
          if (!confirm) {
              this.env.log.warn(`Not installing--here's how to install manually: ${color_1.input(`${manager} ${managerArgs.join(' ')}`)}`);
              return false;
          }
          await this.env.shell.run(manager, managerArgs, { cwd: this.project.directory });
          return true;
      }
      async _runCapacitor(argList) {
          if (!this.project) {
              throw new errors_1.FatalException(`Cannot use Capacitor outside a project directory.`);
          }
          await this.env.shell.run('capacitor', argList, { fatalOnNotFound: false, truncateErrorOutput: 5000, stdio: 'inherit', cwd: this.integration.root });
      }
  }
  exports.CapacitorCommand = CapacitorCommand;
  