//TODO: During next major version bump change to /dist. Leaving at ./form-validator for backwards
//compatibility
const DIST_DIR = './form-validator';
const MAIN_PLUGIN_FILE = 'jquery.form-validator';
const SRC_DIR = './src';
const MAIN_DIR = '/main/';
const MODULE_DIR = '/modules';
const LANG_DIR = '/lang';
const CSS_FILE = 'theme-default.css';
const CORE_VALIDATORS = 'core-validators.js'; //must come at end of concatted file
const coreValidatorsPath = SRC_DIR + MAIN_DIR + CORE_VALIDATORS;

var fs = require('fs'),
  readFile = function (file) {
    return fs.readFileSync(file, 'utf-8');
  },
  replaceInFile = function (path, from, to) {
    fs.writeFileSync(path, readFile(path).replace(from, to));
  };

function initializeGruntConfig(grunt) {

  grunt.initConfig({

    // Import package manifest
    pkg: grunt.file.readJSON("package.json"),

    // Banner definitions
    meta: {
      banner: "/** File generated by Grunt -- do not modify\n" +
      " *  <%= (pkg.title || pkg.name).toUpperCase() %>\n" +
      " *\n" +
      " *  @version <%= pkg.version %>\n" +
      " *  @website <%= pkg.homepage %>\n" +
      " *  @author <%= pkg.author.name %>, <%= pkg.author.url %>\n" +
      " *  @license <%= pkg.license %>\n" +
      " */\n"
    },

    concat: {
      main:{
        files: [
          //This concatenates the core validators file after the other files
          //Per: http://gruntjs.com/configuring-tasks
          {
            src: [SRC_DIR + MAIN_DIR+'*.js', '!' + coreValidatorsPath, coreValidatorsPath],
            dest: DIST_DIR + '/' + MAIN_PLUGIN_FILE + '.js'
          },
          {
            src: [SRC_DIR + MAIN_DIR+'*.js', '!' + coreValidatorsPath, coreValidatorsPath],
            dest: DIST_DIR + '/' + MAIN_PLUGIN_FILE + '.min.js'
          }]
      },
      options: {
        banner: "<%= meta.banner %>"
      }
    },

    cssmin: {
      target: {
        files:   [
          {
            dest: DIST_DIR,
            src: CSS_FILE,
            cwd: SRC_DIR,
            expand: true,
            ext: '.min.css'
          }
        ]
      }
    },
    // Lint definitions
    jshint: {
      files: [SRC_DIR + '/*'],
      options: {
        jshintrc: ".jshintrc",
        ignores: [SRC_DIR + '/' + CSS_FILE]
      }
    },

    // Minify definitions
    uglify: {
      options: {
        banner: "<%= meta.banner %>"
      },
      main: {
        files: [
          {
            expand: true,
            cwd: DIST_DIR + '/',
            src: ['**/*.js', '!' + MAIN_PLUGIN_FILE +'.js'],
            dest: DIST_DIR + '/'
          }
        ]
      }
    },

    // watch for changes to source
    // Better than calling grunt a million times
    // (call 'grunt watch')
    watch: {
      files: [SRC_DIR + '/**'],
      tasks: ['test'],
      options: { nospawn: true}
    },

    // Unit tests
    qunit: {
      all: ['test/qunit.html']
    },

    // Standalone servers
    connect: {
      server: {
        options: {
          port: 8000,
          base: '.',
          keepalive: true
        }
      }
    },

    copy: {
      main: {
        files: [
          {
            src: SRC_DIR + '/' + CSS_FILE,
            dest: DIST_DIR + '/' + CSS_FILE
          },
          {
            cwd: SRC_DIR + '/' + MODULE_DIR,
            src: '**',
            dest: DIST_DIR  + '/',
            expand: true
          },
          {
            cwd: SRC_DIR + '/' + LANG_DIR,
            src: '**',
            dest: DIST_DIR + LANG_DIR +'/',
            expand: true
          }]
      }
    },

    clean: [DIST_DIR + '/'],

    umd: {
      main: {
        options: {
          src: DIST_DIR + '/**/*.js',
          dest: './',
          deps: {
            default: ['jQuery'],
            amd: [{'jquery': 'jQuery'}],
            cjs: [{'jquery': 'jQuery'}]
          }
        }
      }
    }
  });
}

module.exports = function (grunt) {

  initializeGruntConfig(grunt);
  /*
   * Change to new version or the next version number. The project must be built again after this task
   * in order for the version change to take effect.
   */
  grunt.registerTask('version', 'Bump up the version number, or change version name by adding --new-version=3.1.0', function () {
    var pkg = grunt.config.get('pkg'),
      currentVersion = pkg.version,
      newVersion = grunt.option('new-version');

    if (!newVersion) {
      var versionParts = currentVersion.split('.'),
        newSubVersion = parseInt(versionParts.splice(versionParts.length - 1, 1)[0]) + 1;
      newSubVersion = newSubVersion < 10 && newSubVersion > 0 ? '0' + newSubVersion : newSubVersion.toString();
      newVersion = versionParts.join('.') + '.' + newSubVersion;
    }

    grunt.log.writeln('* Moving from version ' + currentVersion + ' to ' + newVersion);

    replaceInFile('package.json', '"version": "' + currentVersion + '"',
      '"version": "' + newVersion + '"');
    replaceInFile('formvalidator.jquery.json', '"version": "' + currentVersion + '"', '"version": "' + newVersion + '"');

    // Set new version globally (can later on be used by concat/uglify)
    pkg.version = newVersion;
    grunt.config.set('pkg', pkg);
  });

  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks("grunt-contrib-concat");
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks("grunt-contrib-jshint");
  grunt.loadNpmTasks("grunt-contrib-uglify");
  grunt.loadNpmTasks("grunt-contrib-watch");
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-umd');

  grunt.registerTask("build-production", ["version", "test", "uglify"]);
  grunt.registerTask('test', ['concat', 'copy', 'umd', 'cssmin','jshint', 'qunit']);
  grunt.registerTask("default", ["test", "watch"]);
  grunt.registerTask("prepublish", ["test", "uglify"]);
};
