/*!
 * @nuxt/cli v2.16.0 (c) 2016-2023
 * Released under the MIT License
 * Repository: https://github.com/nuxt/nuxt.js
 * Website: https://nuxtjs.org
*/
'use strict';

const consola = require('consola');
const chalk = require('chalk');
const opener = require('opener');
const index = require('./cli-index.js');
const banner = require('./cli-banner.js');
require('@nuxt/utils');
require('@nuxt/config');
require('path');
require('exit');
require('std-env');
require('wrap-ansi');
require('boxen');
require('minimist');
require('hable');
require('defu');
require('semver');
require('fs');
require('execa');
require('pretty-bytes');

const dev = {
  name: "dev",
  description: "Start the application in development mode (e.g. hot-code reloading, error reporting)",
  usage: "dev <dir>",
  options: {
    ...index.common,
    ...index.server$1,
    open: {
      alias: "o",
      type: "boolean",
      description: "Opens the server listeners url in the default browser"
    }
  },
  async run(cmd) {
    const { argv } = cmd;
    await this.startDev(cmd, argv, argv.open);
  },
  async startDev(cmd, argv) {
    let nuxt;
    try {
      nuxt = await this._listenDev(cmd, argv);
    } catch (error) {
      consola.fatal(error);
      return;
    }
    try {
      await this._buildDev(cmd, argv, nuxt);
    } catch (error) {
      await nuxt.callHook("cli:buildError", error);
      consola.error(error);
    }
    return nuxt;
  },
  async _listenDev(cmd, argv) {
    const config = await cmd.getNuxtConfig({ dev: true, _build: true });
    const nuxt = await cmd.getNuxt(config);
    nuxt.hook("watch:restart", (payload) => this.onWatchRestart(payload, { nuxt, cmd, argv }));
    nuxt.hook("bundler:change", (changedFileName) => this.onBundlerChange(changedFileName));
    await nuxt.ready();
    await nuxt.server.listen();
    banner.showBanner(nuxt, false);
    if (argv.open) {
      argv.open = false;
      const openerPromises = nuxt.server.listeners.map((listener) => opener(listener.url));
      await Promise.all(openerPromises);
    }
    return nuxt;
  },
  async _buildDev(cmd, argv, nuxt) {
    const builder = await cmd.getBuilder(nuxt);
    await builder.build();
    banner.showMemoryUsage();
    for (const listener of nuxt.server.listeners) {
      consola.info(chalk.bold("Listening on: ") + listener.url);
    }
    return nuxt;
  },
  logChanged({ event, path }) {
    const { icon, color, action } = index.eventsMapping[event] || index.eventsMapping.change;
    consola.log({
      type: event,
      icon: chalk[color].bold(icon),
      message: `${action} ${chalk.cyan(index.formatPath(path))}`
    });
  },
  async onWatchRestart({ event, path }, { nuxt, cmd, argv }) {
    this.logChanged({ event, path });
    await nuxt.close();
    await this.startDev(cmd, argv);
  },
  onBundlerChange(path) {
    this.logChanged({ event: "change", path });
  }
};

exports.default = dev;
