'use strict';

const _ = require('underscore.string');
const path = require('path');
const Base = require('yeoman-generator').Base;
const yosay = require('yosay');
const chalk = require('chalk');

const prompt = require('./prompt');
const write = require('./write');
const pkg = require('../../package.json');

module.exports = class AppGenerator extends Base {

  /**
   * Constructor.
   */
  constructor (...args) {
    super(...args);

    this.argument('appname', {
      type: String,
      required: false
    });

    this.props = {_};
  }

  /**
   * Initialize this generator.
   */
  get initializing () {
    return {

      /**
       * Get version.
       */
      version () {
        this.version = pkg.version;
      },

      /**
       * Set app name.
       */
      appName () {
        this.props.appname = this.appname || path.basename(process.cwd());
        this.props.appname = _.slugify(_.humanize(this.props.appname));
      },

      /**
       * Define template context.
       */
      paths () {
        this.sourceRoot(path.join(__dirname, '../../templates/app'));
      },

      /**
       * Display a welcome message.
       */
      welcome () {
        this.log(yosay(
          `Welcome to the ${chalk.red('Webpack Angular')} generator!`
        ));
      }
    };
  }

  /**
   * Prompt the user for options.
   */
  prompting () {
    return prompt.questions(this);
  }

  /**
   * Write configuration files.
   */
  get configuring () {
    return {

      /**
       * Write configuration files.
       */
      configFiles () {
        this.fs.copyTpl(
          this.templatePath('_.babelrc'),
          this.destinationPath('.babelrc')
        );

        this.fs.copyTpl(
          this.templatePath('_.editorconfig'),
          this.destinationPath('.editorconfig')
        );

        this.fs.copyTpl(
          this.templatePath('_.gitignore'),
          this.destinationPath('.gitignore')
        );
      },

      /**
       * Write package.json.
       */
      packageJSON () {
        this.fs.copyTpl(
          this.templatePath('_package.json'),
          this.destinationPath('package.json'),
          this.props
        );
      },

      /**
       * Write linter files
       */
      linters () {
        this.fs.copyTpl(
          this.templatePath('src/_.htmlhintrc'),
          this.destinationPath('src/.htmlhintrc')
        );

        this.fs.copyTpl(
          this.templatePath('src/_.eslintrc'),
          this.destinationPath('src/.eslintrc')
        );

        switch (this.props.cssPreprocessor) {
          case 'css':
            this.fs.copyTpl(
              this.templatePath('src/_.csslintrc'),
              this.destinationPath('src/.csslintrc')
            );
            break;

          default:
          case 'sass':
            this.fs.copyTpl(
              this.templatePath('src/_.sass-lint.yml'),
              this.destinationPath('src/.sass-lint.yml')
            );
            break;
        }
      }
    };
  }

  /**
   * Write project files.
   */
  get writing () {
    return write;
  }

  /**
   * Install dependencies.
   */
  install () {
    switch (this.props.packageManager) {
      case 'yarn':
        this.runInstall('yarn', '--ignore-optional');
        break;

      default:
      case 'npm':
        this.npmInstall();
        break;
    }
  }

  /**
   * Say goodbye.
   */
  end () {
    this.log(`It's time to use ${this.props.packageManager.charAt(0).toUpperCase() + this.props.packageManager.slice(1)} scripts:`);
    this.log(`- ${chalk.yellow.bold(`${this.props.packageManager} run build`)} to build an optimized version of your application in folder /dist`);
    this.log(`- ${chalk.yellow.bold(`${this.props.packageManager} run build:prod`)} to build an optimized version of your application in folder /dist in a ${chalk.yellow.bold('production')} environment`);
    this.log(`- ${chalk.yellow.bold(`${this.props.packageManager} start`)} to launch ${chalk.bold('npm run server')} and ${chalk.bold('json-server')} (if checked in generator) in parallel`);
    this.log(`- ${chalk.yellow.bold(`${this.props.packageManager} run serve`)} to launch a webpack-dev-server server on your source files`);
    this.log(`- ${chalk.yellow.bold(`${this.props.packageManager} run serve:prod`)} to launch a webpack-dev-server server on your source files in a ${chalk.yellow.bold('production')} environment`);
    this.log(`- ${chalk.yellow.bold(`${this.props.packageManager} run test`)} to launch your unit tests with Karma`);
    this.log(`- ${chalk.yellow.bold(`${this.props.packageManager} run lint`)} to launch linting process`);
    if (this.props.sonarWebFrontendReporters) {
      this.log(`- ${chalk.yellow.bold(`${this.props.packageManager} run sonar:reporters`)} to create the linters reporters for SonarQube plugin`);
    }
  }
};

@@ -3601,86 +3601,129 @@
 er%7D 
-run build%60)%7D to build an optimized version of your application in folder /dist
+start%60)%7D to launch $%7Bchalk.bold('npm run server')%7D and $%7Bchalk.bold('json-server')%7D (if checked in generator) in parallel
 %60);%0A
@@ -3796,330 +3796,273 @@
 run 
-build:prod%60)%7D to build an optimized versi
+serve%60)%7D to launch a webpack-dev-server server 
 on 
-of 
 your 
-application in folder /dist in a $%7Bchalk.yellow.bold('production')%7D environment%60);%0A    this.log(%60- $%7Bchalk.yellow.bold(%60$%7Bthis.props.packageManager%7D start%60)%7D to launch $%7Bchalk.bold('npm run server')%7D and $%7Bchalk.bold('json-server')%7D (if checked in generator) in parallel
+source files%60);%0A    this.log(%60- $%7Bchalk.yellow.bold(%60$%7Bthis.props.packageManager%7D run serve:prod%60)%7D to launch a webpack-dev-server server on your source files in a $%7Bchalk.yellow.bold('production')%7D environment
 %60);%0A
@@ -4135,75 +4135,82 @@
 run 
-serve
+build
 %60)%7D to 
-launch a webpack-dev-server server on
+build an optimized version of
  your 
-source files
+application in folder /dist
 %60);%0A
@@ -4271,37 +4271,37 @@
 ageManager%7D run 
-serve
+build
 :prod%60)%7D to laun
@@ -4300,63 +4300,70 @@
  to 
-launch a webpack-dev-server server on your source files
+build an optimized version of your application in folder /dist
  in 
@@ -4836,19 +4836,171 @@
 in%60);%0A    %7D%0A
+    if (this.props.jsonServer) %7B%0A      this.log(%60- $%7Bchalk.yellow.bold(%60$%7Bthis.props.packageManager%7D run json-server%60)%7D to start a json-server%60);%0A    %7D%0A
   %7D%0A%7D;%0A

add json-server script