// Generated on 2020-12-09 using generator-fng 0.2.23
"use strict";

module.exports = function (grunt) {
  var localConfig;
  try {
    // noinspection JSFileReferences
    localConfig = require("./lib/config/env/local.env");
  } catch (e) {
    localConfig = {};
  }

  // Load grunt tasks automatically, when needed
  require("jit-grunt")(grunt, {
    express: "grunt-express-server",
    useminPrepare: "grunt-usemin",
    ngtemplates: "grunt-angular-templates",
    buildcontrol: "grunt-build-control",
  });

  // Time how long tasks take. Can help when optimizing build times
  require("time-grunt")(grunt);

  // Define the configuration for all the tasks
  grunt.initConfig({
    // Project settings
    pkg: grunt.file.readJSON("package.json"),
    yeoman: {
      // configurable paths
      client: "app",
      app: "app",
      dist: "dist",
    },
    express: {
      options: {
        port: process.env.PORT || 9000,
      },
      dev: {
        options: {
          script: "server.js",
          debug: true,
        },
      },
      prod: {
        options: {
          script: "server.js",
        },
      },
    },
    open: {
      server: {
        url: "http://localhost:<%= express.options.port %>",
      },
    },
    watch: {
      injectJS: {
        files: [
          "<%= yeoman.client %>/{app,components}/**/*.js",
          "!<%= yeoman.client %>/{app,components}/**/*.spec.js",
          "!<%= yeoman.client %>/{app,components}/**/*.mock.js",
          "!<%= yeoman.client %>/app/scripts/app.js",
        ],
        tasks: ["injector:scripts"],
      },
      injectCss: {
        files: ["<%= yeoman.client %>/{app,components}/**/*.css"],
        tasks: ["injector:css"],
      },
      mochaTest: {
        files: ["server/**/*.spec.js"],
        tasks: ["env:test", "mochaTest"],
      },
      jsTest: {
        files: [
          "<%= yeoman.client %>/{app,components}/**/*.spec.js",
          "<%= yeoman.client %>/{app,components}/**/*.mock.js",
        ],
        tasks: ["newer:jshint:all", "karma"],
      },
      less: {
        files: ["<%= yeoman.app %>/styles/{,*/}*.less"],
        tasks: ["newer:less"],
      },
      gruntfile: {
        files: ["Gruntfile.js"],
      },
      livereload: {
        files: [
          "{.tmp,<%= yeoman.client %>}/{app,components}/**/*.css",
          "{.tmp,<%= yeoman.client %>}/{app,components}/**/*.html",
          "{.tmp,<%= yeoman.client %>}/{app,components}/**/*.js",
          "!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.spec.js",
          "!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.mock.js",
          "<%= yeoman.client %>/images/{,*//*}*.{png,jpg,jpeg,gif,webp,svg}",
        ],
        options: {
          livereload: true,
        },
      },
      express: {
        files: ["server/**/*.{js,json}"],
        tasks: ["express:dev", "wait"],
        options: {
          livereload: true,
          nospawn: true, //Without this option specified express won't be reloaded
        },
      },
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: "<%= yeoman.client %>/.jshintrc",
        reporter: require("jshint-stylish"),
      },
      server: {
        options: {
          jshintrc: "server/.jshintrc",
        },
        src: ["server/**/*.js", "!server/**/*.spec.js"],
      },
      serverTest: {
        options: {
          jshintrc: "server/.jshintrc-spec",
        },
        src: ["server/**/*.spec.js"],
      },
      all: [
        "<%= yeoman.client %>/{app,components}/**/*.js",
        "!<%= yeoman.client %>/{app,components}/**/*.spec.js",
        "!<%= yeoman.client %>/{app,components}/**/*.mock.js",
      ],
      test: {
        src: [
          "<%= yeoman.client %>/{app,components}/**/*.spec.js",
          "<%= yeoman.client %>/{app,components}/**/*.mock.js",
        ],
      },
    },

    // Empties folders to start fresh
    clean: {
      dist: {
        files: [
          {
            dot: true,
            src: [
              ".tmp",
              "<%= yeoman.dist %>/*",
              "!<%= yeoman.dist %>/.git*",
              "!<%= yeoman.dist %>/.openshift",
              "!<%= yeoman.dist %>/Procfile",
            ],
          },
        ],
      },
      server: ".tmp",
    },

    // Add vendor prefixed styles
    autoprefixer: {
      options: {
        browsers: ["last 1 version"],
      },
      dist: {
        files: [
          {
            expand: true,
            cwd: ".tmp/",
            src: "{,*/}*.css",
            dest: ".tmp/",
          },
        ],
      },
    },

    // Debugging with node inspector
    "node-inspector": {
      custom: {
        options: {
          "web-host": "localhost",
        },
      },
    },

    // compile less into css
    less: {
      dist: {
        options: {
          compile: true,
          math: "always",
        },
        files: {
          "<%= yeoman.app %>/styles/main-bs2.css": [
            "<%= yeoman.app %>/styles/demo-bs2.less",
          ],
          "<%= yeoman.app %>/styles/main-bs3.css": [
            "<%= yeoman.app %>/styles/demo-bs3.less",
          ],
        },
      },
    },

    // Use nodemon to run server in debug mode with an initial breakpoint
    nodemon: {
      debug: {
        script: "server.js",
        options: {
          nodeArgs: ["--inspect-brk"],
          env: {
            PORT: process.env.PORT || 9000,
          },
          callback: function (nodemon) {
            nodemon.on("log", function (event) {
              console.log(event.colour);
            });

            // opens browser on initial server start
            nodemon.on("config:update", function () {
              setTimeout(function () {
                require("open")("http://localhost:8080/debug?port=5858");
              }, 500);
            });
          },
        },
      },
    },

    concat: {
      options: {
        process: function (src, filepath) {
          // output an extra semicolon when concatenating javascripts
          if (/\.js$/.test(filepath)) {
            return src + ";";
          }

          return src;
        },
      },
    },

    // // Automatically inject Bower components into the app
    // wiredep: {
    //   target: {
    //     src: '<%= yeoman.client %>/index.html',
    //     ignorePath: '<%= yeoman.client %>/',
    //     exclude: [
    //       /bootstrap-sass-official/,
    //       /bootstrap.js/,
    //       '/json3/',
    //       '/es5-shim/'
    //       , /blueimp-file-upload\/js\/jquery.fileupload-ui.js/, /blueimp-file-upload\/js\/jquery.fileupload-jquery-ui.js/
    //
    //       ,  /ckeditor\/ckeditor.js/
    //     ]
    //   }
    // },
    //
    // Renames files for browser caching purposes
    rev: {
      dist: {
        files: {
          src: [
            "<%= yeoman.dist %>/public/{,*/}*.js",
            "<%= yeoman.dist %>/public/{,*/}*.css",
            "<%= yeoman.dist %>/public/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}",
            "<%= yeoman.dist %>/public/fonts/*",
          ],
        },
      },
    },

    // Reads HTML for usemin blocks to enable smart builds that automatically
    // concat, minify and revision files. Creates configurations in memory so
    // additional tasks can operate on them
    useminPrepare: {
      html: ["<%= yeoman.client %>/index.html"],
      options: {
        dest: "<%= yeoman.dist %>/public",
      },
    },

    // Performs rewrites based on rev and the useminPrepare configuration
    usemin: {
      html: ["<%= yeoman.dist %>/public/{,*/}*.html"],
      css: ["<%= yeoman.dist %>/public/{,*/}*.css"],
      js: ["<%= yeoman.dist %>/public/{,*/}*.js"],
      options: {
        assetsDirs: [
          "<%= yeoman.dist %>/public",
          "<%= yeoman.dist %>/public/images",
        ],
        // This is so we update image references in our ng-templates
        patterns: {
          js: [
            [
              /(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm,
              "Update the JS to reference our revved images",
            ],
          ],
        },
      },
    },

    // The following *-min tasks produce minified files in the dist folder
    imagemin: {
      dist: {
        files: [
          {
            expand: true,
            cwd: "<%= yeoman.client %>/images",
            src: "{,*/}*.{png,jpg,jpeg,gif}",
            dest: "<%= yeoman.dist %>/public/images",
          },
        ],
      },
    },

    svgmin: {
      dist: {
        files: [
          {
            expand: true,
            cwd: "<%= yeoman.client %>/images",
            src: "{,*/}*.svg",
            dest: "<%= yeoman.dist %>/public/images",
          },
        ],
      },
    },

    // Allow the use of non-minsafe AngularJS files. Automatically makes it
    // minsafe compatible so Uglify does not destroy the ng references
    ngAnnotate: {
      dist: {
        files: [
          {
            expand: true,
            cwd: ".tmp/concat",
            src: "*/**.js",
            dest: ".tmp/concat",
          },
        ],
      },
    },

    // Package all the html partials into a single javascript payload
    ngtemplates: {
      options: {
        // This should be the name of your apps angular module
        module: "tmpApp",
        htmlmin: {
          collapseBooleanAttributes: true,
          collapseWhitespace: true,
          removeAttributeQuotes: true,
          removeEmptyAttributes: true,
          removeRedundantAttributes: true,
          removeScriptTypeAttributes: true,
          removeStyleLinkTypeAttributes: true,
        },
        usemin: "app/scripts/app.js",
      },
      main: {
        cwd: "<%= yeoman.client %>",
        src: ["{app,components}/**/*.html"],
        dest: ".tmp/templates.js",
      },
      tmp: {
        cwd: ".tmp",
        src: ["{app,components}/**/*.html"],
        dest: ".tmp/tmp-templates.js",
      },
    },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [
          {
            expand: true,
            dot: true,
            cwd: "<%= yeoman.client %>",
            dest: "<%= yeoman.dist %>/public",
            src: [
              "*.{ico,png,txt}",
              ".htaccess",
              "bower_components/**/*",
              "images/{,*/}*.{webp}",
              "fonts/**/*",
              "index.html",
            ],
          },
          {
            expand: true,
            cwd: ".tmp/images",
            dest: "<%= yeoman.dist %>/public/images",
            src: ["generated/*"],
          },
          {
            expand: true,
            dest: "<%= yeoman.dist %>",
            src: ["package.json", "server/**/*"],
          },
        ],
      },
      css: {
        files: [
          {
            dest: "<%= yeoman.dist %>/public/styles/main-bs2.css",
            src: "app/styles/main-bs2.css",
          },
          {
            dest: "<%= yeoman.dist %>/public/styles/main-bs3.css",
            src: "app/styles/main-bs3.css",
          },
        ],
      },
    },

    buildcontrol: {
      options: {
        dir: "dist",
        commit: true,
        push: true,
        connectCommits: false,
        message:
          "Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%",
      },
      heroku: {
        options: {
          remote: "heroku",
          branch: "master",
        },
      },
      openshift: {
        options: {
          remote: "openshift",
          branch: "master",
        },
      },
    },

    // Run some tasks in parallel to speed up the build process
    concurrent: {
      server: [],
      test: [],
      debug: {
        tasks: ["nodemon", "node-inspector"],
        options: {
          logConcurrentOutput: true,
        },
      },
      dist: ["imagemin", "svgmin"],
    },

    // Test settings
    karma: {
      unit: {
        configFile: "test/karma.conf.js",
        singleRun: true,
      },
    },

    mochaTest: {
      options: {
        reporter: "spec",
        "forbid-only": true,
      },
      src: ["server/**/*.spec.js", "test/server/**/*.spec.js"],
    },

    env: {
      test: {
        NODE_ENV: "test",
      },
      prod: {
        NODE_ENV: "production",
      },
      all: localConfig,
    },

    injector: {
      options: {},
      // Inject application script files into index.html (doesn't include bower)
      scripts: {
        options: {
          transform: function (filePath) {
            filePath = filePath.replace("/client/", "");
            filePath = filePath.replace("/.tmp/", "");
            return '<script src="' + filePath + '"></script>';
          },
          starttag: "<!-- injector:js -->",
          endtag: "<!-- endinjector -->",
        },
        files: {
          "<%= yeoman.client %>/index.html": [
            [
              "{.tmp,<%= yeoman.client %>}/{app,components}/**/*.js",
              "!{.tmp,<%= yeoman.client %>}/app/scripts/app.js",
              "!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.spec.js",
              "!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.mock.js",
            ],
          ],
        },
      },
      less: {
        options: {
          transform: function (filePath) {
            filePath = filePath.replace("/app/", "");
            filePath = filePath.replace("/client/components/", "");
            return '@import "' + filePath + '";';
          },
          starttag: "// injector",
          endtag: "// endinjector",
        },
        files: {
          "<%= yeoman.client %>/styles/demo-bs2.less": [
            "<%= yeoman.client %>/**/*.less",
            "!<%= yeoman.client %>/styles/demo-bs2.less",
          ],
          "<%= yeoman.client %>/styles/demo-bs3.less": [
            "<%= yeoman.client %>/**/*.less",
            "!<%= yeoman.client %>/styles/demo-bs3.less",
          ],
        },
      },
      // Inject component css into index.html
      css: {
        options: {
          transform: function (filePath) {
            filePath = filePath.replace("/client/", "");
            filePath = filePath.replace("/.tmp/", "");
            return '<link rel="stylesheet" href="' + filePath + '">';
          },
          starttag: "<!-- injector:css -->",
          endtag: "<!-- endinjector -->",
        },
        files: {
          "<%= yeoman.client %>/index.html": [
            "<%= yeoman.client %>/{app,components}/**/*.css",
          ],
        },
      },
    },

    shell: {
      makeProductionIndex: "node setUpIndexHTML.js production",
      resetDevelopmentIndex: "node setUpIndexHTML.js development",
      playwright:
        "npx playwright test test/playwright/*.spec.ts --project=chromium --workers 1",
    },
  });

  // Used for delaying livereload until after server has restarted
  grunt.registerTask("wait", function () {
    grunt.log.ok("Waiting for server reload...");

    var done = this.async();

    setTimeout(function () {
      grunt.log.writeln("Done waiting!");
      done();
    }, 1500);
  });

  grunt.registerTask("express-keepalive", "Keep grunt running", function () {
    this.async();
  });

  grunt.registerTask("serve", function (target) {
    if (target === "dist") {
      return grunt.task.run([
        "build",
        "env:all",
        "env:prod",
        "express:prod",
        "wait",
        "open",
        "express-keepalive",
      ]);
    }

    if (target === "debug") {
      return grunt.task.run([
        "clean:server",
        "less",
        "env:all",
        "concurrent:server",
        "injector",
        // 'wiredep',
        "autoprefixer",
        "concurrent:debug",
      ]);
    }

    grunt.task.run([
      "clean:server",
      "less",
      "env:all",
      "concurrent:server",
      "injector",
      // 'wiredep',
      "autoprefixer",
      "express:dev",
      "wait",
      "open",
      "watch",
    ]);
  });

  grunt.registerTask("server", function () {
    grunt.log.warn(
      "The `server` task has been deprecated. Use `grunt serve` to start a server."
    );
    grunt.task.run(["serve"]);
  });

  grunt.registerTask("test", function (target) {
    if (target === "server") {
      return grunt.task.run(["env:all", "env:test", "mochaTest"]);
    } else if (target === "client") {
      return grunt.task.run([
        "clean:server",
        "less",
        "env:all",
        "concurrent:test",
        "injector",
        "autoprefixer",
        "karma",
      ]);
    } else if (target === "e2e") {
      return grunt.task.run([
        "clean:server",
        "less",
        "env:all",
        "env:test",
        "concurrent:test",
        "injector",
        // 'wiredep',
        "autoprefixer",
        "express:dev",
        "shell:playwright",
      ]);
    } else if (target === "screens") {
      return grunt.task.run([
        "prepare",
        "express:test",
        "protractor:bs2_320x480",
        "protractor:bs3_320x480",
        "protractor:bs2_1024x768",
        "protractor:bs3_1024x768",
      ]);
    } else {
      grunt.task.run([
        "test:server",
        "test:client",
        "test:e2e",
        // 'test:screens'  Not a lot of point as not comparing them at the moment
      ]);
    }
  });

  grunt.registerTask("build", [
    "clean:dist",
    "injector:less",
    "less:dist",
    "concurrent:dist",
    "injector",
    // // 'wiredep',
    "shell:makeProductionIndex",
    "useminPrepare",
    "autoprefixer",
    "ngtemplates",
    "concat",
    "ngAnnotate",
    "copy:dist",
    "cssmin",
    "uglify",
    "rev",
    "usemin",
    "copy:css",
    "shell:resetDevelopmentIndex",
  ]);

  grunt.registerTask("default", ["newer:jshint", "test", "build"]);
};
