'use strict';

var util = require('util');

module.exports = function(grunt) {
  /*jshint maxstatements:false */

  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

  grunt.initConfig({

    config: {
      appName: 'etcd-dashboard',
      appPath: 'app',
      bowerPath: 'app/bower_components',
      tmpPath: '.tmp',
      distPath: 'dist'
    },

    watch: {
      css: {
        files: ['<%= config.appPath %>/{page,ui,style}/{**/,}*.scss'],
        tasks: ['sass']
      },
      html: {
        files: [
          '<%= config.appPath %>/{module,ui,page}/**/*.html'
        ],
        tasks: ['views']
      },
      js: {
        files: [
          '<%= config.appPath %>/{module,page}/**/*.js',
          '<%= config.appPath %>/*.js'
        ],
        tasks: ['jshint']
      }
    },

    concurrent: {
      dev: {
        tasks: [
          'watch',
          //'test-watch'
        ],
        options: {
          logConcurrentOutput: true
        }
      }
    },

    clean: {
      tmp: {
        files: [{
          dot: true,
          src: [
            '<%= config.tmpPath %>',
            '.sass-cache/**/*'
          ]
        }]
      },
      dist: {
        files: [{
          dot: true,
          src: [
            '<%= config.distPath %>/*'
          ]
        }]
      },
      'dist-static': {
        files: [{
          dot: true,
          src: [
            '<%= config.distPath %>/cp/**'
          ]
        }]
      },
      compiled: {
        files: [{
          dot: true,
          src: [
            '<%= config.appPath %>/compiled/**'
          ]
        }]
      }
    },

    // JS code linting.
    jshint: {
      options: {
        camelcase: true,
        curly: true,
        eqeqeq: true,
        eqnull: true,
        forin: true,
        freeze: true,
        immed: true,
        indent: 2,
        latedef: true,
        maxcomplexity: 10,
        maxdepth: 3,
        maxlen: 80,
        maxparams: 20,
        maxstatements: 200,
        newcap: true,
        noarg: true,
        node: true,
        noempty: true,
        nonew: true,
        nonbsp: true,
        quotmark: 'single',
        strict: true,
        sub: true,
        trailing: true,
        undef: true,
        unused: true
      },
      src: {
        node: false,
        options: {
          globals: {
            angular: true,
            window: true
          }
        },
        files: {
          src: [
            '<%= config.appPath %>/*.js',
            '<%= config.appPath %>/{module,page}**/*.js',
            '!<%= config.appPath %>/vega.js'
          ]
        }
      }
    },

    // Compile SCSS to CSS.
    sass: {
      etcd: {
        options: {
          includePaths: ['<%= config.appPath %>/coreos-web/sass'],
          outputStyle: 'nested'
        },
        files: {
          '<%= config.appPath %>/compiled/main.css': '<%= config.appPath %>/main.scss'
        }
      }
    },

    /**
     * Generate grunt configs for concat, uglify, cssmin.
     */
    useminPrepare: {
      html: '<%= config.appPath %>/index.html',
      options: {
        dest: '<%= config.distPath %>'
      }
    },

    usemin: {
      html: ['<%= config.distPath %>/index.html']
    },

    // This block gets generated by usemin.
    cssmin: {
    },

    // This block gets generated by usemin.
    uglify: {
    },

    // This block gets generated by usemin.
    concat: {
    },

    // Make our angular code minification friendly.
    ngmin: {
      dist: {
        files: [{
          src: '<%= config.tmpPath %>/concat/app.js',
          dest: '<%= config.tmpPath %>/concat/app.js'
        }]
      }
    },

    copy: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= config.appPath %>',
          src: ['index.html'],
          dest: '<%= config.distPath %>'
        }]
      },
      images: {
        files: [{
          expand: true,
          cwd: '<%= config.appPath %>/img',
          src: ['**'],
          dest: '<%= config.distPath %>/img'
        }]
      },
      'coreos-web': {
        files: [{
          cwd: '<%= config.appPath %>/coreos-web',
          expand: true,
          src: [
            'fonts/*',
            'img/*'
          ],
          dest: '<%= config.distPath %>/coreos-web'
        }]
      },
      'dist-static': {
        files: [
          {
            expand: true,
            flatten: true,
            src: [
              '<%= config.distPath %>/cp/static/*'
            ],
            dest: '<%= config.distPath %>'
          }
        ]
      }
    },

    // Precompile html views into a single javascript file.
    html2js: {
      options: {
        base: '<%= config.appPath %>',
        rename: function(moduleName) {
          return '/' + moduleName;
        }
      },
      views: {
        src: [
          '<%= config.appPath %>/{page,ui,module}/**/*.html'
        ],
        dest: '<%= config.appPath %>/compiled/views.js'
      }
    }

  });

  grunt.registerTask('clean-paths', 'clean up resource paths', function() {
    grunt.log.writeln('cleaning paths...');
    function clean(path) {
      return path.replace('mod/dashboard/static/', '');
    }
    ['concat', 'uglify', 'cssmin'].forEach(function(task) {
      var config = grunt.config(task);

      config.generated.files.forEach(function(fileGroup) {
        fileGroup.dest = clean(fileGroup.dest);
        fileGroup.src = fileGroup.src.map(function(path) {
          return clean(path);
        });
      });
      grunt.config(task, config);
      grunt.log.ok(task + ' config is now:');
      grunt.log.writeln(util.inspect(grunt.config(task), false, 4, true));
    });
  });

  grunt.registerTask('test', [
    'views',
    'karma:unit'
  ]);

  grunt.registerTask('test-watch', [
    'karma:dev'
  ]);

  grunt.registerTask('views', [
    'html2js:views'
  ]);

  grunt.registerTask('dev', [
    'clean',
    'jshint',
    'views',
    'sass',
    'concurrent:dev'
  ]);

  grunt.registerTask('build', [
    'clean',
    'jshint',
    'views',
    //'test',
    'sass',
    'useminPrepare',
    'clean-paths',
    'concat',
    'ngmin:dist',
    'uglify',
    'cssmin',
    'copy:dist',
    'usemin',
    'copy:dist-static',
    'clean:dist-static',
    'copy:images',
    'copy:coreos-web'
  ]);

  grunt.registerTask('default', ['build']);
};
