const sass = require('node-sass');

module.exports = function (grunt) {
  // Full list of files that must be included by RequireJS
  includes = [
    'jquery.select2',
    'almond',

    'jquery-mousewheel' // shimmed for non-full builds
  ];

  fullIncludes = [
    'jquery',

    'select2/compat/containerCss',
    'select2/compat/dropdownCss',

    'select2/compat/initSelection',
    'select2/compat/inputData',
    'select2/compat/matcher',
    'select2/compat/query',

    'select2/dropdown/attachContainer',
    'select2/dropdown/stopPropagation',

    'select2/selection/stopPropagation'
  ].concat(includes);

  var i18nModules = [];
  var i18nPaths = {};

  var i18nFiles = grunt.file.expand({
    cwd: 'src/js'
  }, 'select2/i18n/*.js');

  var testFiles = grunt.file.expand('tests/**/*.html');
  var testUrls = testFiles.map(function (filePath) {
    return 'http://localhost:9999/' + filePath;
  });

  var testBuildNumber = "unknown";

  if (process.env.TRAVIS_JOB_ID) {
    testBuildNumber = "travis-" + process.env.TRAVIS_JOB_ID;
  } else {
    var currentTime = new Date();

    testBuildNumber = "manual-" + currentTime.getTime();
  }

  for (var i = 0; i < i18nFiles.length; i++) {
    var file = i18nFiles[i];
    var name = file.split('.')[0];

    i18nModules.push({
      name: name
    });

    i18nPaths[name] = '../../' + name;
  }

  var minifiedBanner = '/*! Select2 <%= package.version %> | https://github.com/select2/select2/blob/master/LICENSE.md */';

  grunt.initConfig({
    package: grunt.file.readJSON('package.json'),

    concat: {
      'dist': {
        options: {
          banner: grunt.file.read('src/js/wrapper.start.js'),
        },
        src: [
          'dist/js/select2.js',
          'src/js/wrapper.end.js'
        ],
        dest: 'dist/js/select2.js'
      },
      'dist.full': {
        options: {
          banner: grunt.file.read('src/js/wrapper.start.js'),
        },
        src: [
          'dist/js/select2.full.js',
          'src/js/wrapper.end.js'
        ],
        dest: 'dist/js/select2.full.js'
      }
    },

    connect: {
      tests: {
        options: {
          base: '.',
          hostname: '127.0.0.1',
          port: 9999
        }
      }
    },

    uglify: {
      'dist': {
        src: 'dist/js/select2.js',
        dest: 'dist/js/select2.min.js',
        options: {
          banner: minifiedBanner
        }
      },
      'dist.full': {
        src: 'dist/js/select2.full.js',
        dest: 'dist/js/select2.full.min.js',
        options: {
          banner: minifiedBanner
        }
      }
    },

    qunit: {
      all: {
        options: {
          urls: testUrls
        }
      }
    },

    jshint: {
      options: {
        jshintrc: true,
        reporterOutput: ''
      },
      code: {
        src: ['src/js/**/*.js']
      },
      tests: {
        src: ['tests/**/*.js']
      }
    },

    sass: {
      dist: {
        options: {
          implementation: sass,
          outputStyle: 'compressed'
        },
        files: {
          'dist/css/select2.min.css': [
            'src/scss/core.scss',
            'src/scss/theme/default/layout.css'
          ]
        }
      },
      dev: {
        options: {
          implementation: sass,
          outputStyle: 'nested'
        },
        files: {
          'dist/css/select2.css': [
            'src/scss/core.scss',
            'src/scss/theme/default/layout.css'
          ]
        }
      }
    },

    requirejs: {
      'dist': {
        options: {
          baseUrl: 'src/js',
          optimize: 'none',
          name: 'select2/core',
          out: 'dist/js/select2.js',
          include: includes,
          namespace: 'S2',
          paths: {
            'almond': require.resolve('almond').slice(0, -3),
            'jquery': 'jquery.shim',
            'jquery-mousewheel': 'jquery.mousewheel.shim'
          },
          wrap: {
            startFile: 'src/js/banner.start.js',
            endFile: 'src/js/banner.end.js'
          }
        }
      },
      'dist.full': {
        options: {
          baseUrl: 'src/js',
          optimize: 'none',
          name: 'select2/core',
          out: 'dist/js/select2.full.js',
          include: fullIncludes,
          namespace: 'S2',
          paths: {
            'almond': require.resolve('almond').slice(0, -3),
            'jquery': 'jquery.shim',
            'jquery-mousewheel': require.resolve('jquery-mousewheel').slice(0, -3)
          },
          wrap: {
            startFile: 'src/js/banner.start.js',
            endFile: 'src/js/banner.end.js'
          }
        }
      },
      'i18n': {
        options: {
          baseUrl: 'src/js/select2/i18n',
          dir: 'dist/js/i18n',
          paths: i18nPaths,
          modules: i18nModules,
          namespace: 'S2',
          wrap: {
            start: minifiedBanner + grunt.file.read('src/js/banner.start.js'),
            end: grunt.file.read('src/js/banner.end.js')
          }
        }
      }
    },

    watch: {
      js: {
        files: [
          'src/js/select2/**/*.js',
          'tests/**/*.js'
        ],
        tasks: [
          'compile',
          'test',
          'minify'
        ]
      },
      css: {
        files: [
          'src/scss/**/*.scss'
        ],
        tasks: [
          'compile',
          'minify'
        ]
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.loadNpmTasks('grunt-sass');

  grunt.registerTask('default', ['compile', 'test', 'lint', 'minify']);

  grunt.registerTask('compile', [
    'requirejs:dist', 'requirejs:dist.full', 'requirejs:i18n',
    'concat:dist', 'concat:dist.full',
    'sass:dev'
  ]);
  grunt.registerTask('minify', ['uglify', 'sass:dist']);
  grunt.registerTask('lint', ['jshint']);
  grunt.registerTask('test', ['connect:tests', 'qunit']);
};
