'use strict'

#!
# esefpy-seed
# https://bitbucket.org/egemsoft/esefpy-seed
# Copyright (c) 2015, Egemsoft
#

module.exports = (grunt) ->

  # Load grunt tasks automatically
  require('load-grunt-tasks') grunt
  # Time how long tasks take. Can help when optimizing build times
  require('time-grunt') grunt

  # Configurable paths for the application
  appConfig =
    src: 'web/app'
    dist: 'web/dist'
    module: '<%= projectNameCC %>'
    name: '<%= projectName %>'


  # Define the configuration for all the tasks
  grunt.initConfig
    appConfig: appConfig

    watch:
      bower:
        files: ['bower.json']
        tasks: ['wiredep']
      coffee:
        files: ['<%%= appConfig.src %>/scripts/{,**/}*.{coffee,litcoffee,coffee.md}']
        tasks: ['newer:coffee:dist']
      coffeeTest:
        files: ['web/test/spec/{,**/}*.{coffee,litcoffee,coffee.md}']
        tasks: [
          'newer:coffee:test'
          'karma'
        ]
      scripts:
        files: ['<%%= appConfig.src %>/scripts/{,**/}*.js']
        tasks: ['newer:copy:scripts']
      scriptsTest:
        files: ['web/test/spec/{,**/}*.js']
        tasks: ['newer:copy:scripts']
      styles:
        files: ['<%%= appConfig.src %>/styles/{,**/}*.css']
        tasks: [
          'newer:copy:styles'
          'autoprefixer'
        ]
      gruntfile:
        files: ['Gruntfile.coffee']
      livereload:
        options:
          livereload: '<%%= connect.options.livereload %>'
        files: [
          '<%%= appConfig.src %>/{,**/}*.html'
          '.tmp/styles/{,**/}*.css'
          '.tmp/scripts/{,**/}*.js'
          '<%%= appConfig.src %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]


    connect:
      options:
        port: 9000
        hostname: 'localhost'
        livereload: 35729
      proxies: [
        context: ['/api', '/static', '/restauth', '/_meta', '/admin']
        host: 'localhost'
        port: 8000
      ]
      livereload:
        options:
          open: true
          middleware: (connect) ->
            [
              require('grunt-connect-proxy/lib/utils').proxyRequest
              connect.static('.tmp')
              connect().use('/bower_components', connect.static('./web/bower_components'))
              connect().use('/app/styles', connect.static('./web/app/styles'))
              connect.static(appConfig.src)
            ]
      test:
        options:
          port: 9001
          middleware: (connect) ->
            [
              connect.static('.tmp')
              connect.static('web/test')
              connect().use('/web/bower_components', connect.static('./web/bower_components'))
              connect.static(appConfig.src)
            ]
      dist:
        options:
          open: true
          middleware: (connect) ->
            [
              require('grunt-connect-proxy/lib/utils').proxyRequest
              connect.static(appConfig.dist)
            ]


    jshint:
      options:
        jshintrc: '.jshintrc'
        reporter: require('jshint-stylish')
      all:
        src: ['Gruntfile.js']


    clean:
      dist:
        files: [{
          dot: true
          src: [
            '.tmp'
            '<%%= appConfig.dist %>/{,*/}*'
            '!<%%= appConfig.dist %>/.git{,*/}*'
          ]
        }]
      server: '.tmp'


    autoprefixer:
      options:
        browsers: ['last 1 version']
      server:
        options:
          map: true
        files: [{
          expand: true
          cwd: '.tmp/styles/'
          src: '{,**/}*.css'
          dest: '.tmp/styles/'
        }]
      dist:
        files: [{
          expand: true
          cwd: '.tmp/styles/'
          src: '{,**/}*.css'
          dest: '.tmp/styles/'
        }]


    wiredep:
      app:
        src: ['<%%= appConfig.src %>/index.html']
        ignorePath: /\.\.\//
        exclude: ['egemswatch', 'jquery', 'es5-shim', 'json3']
      test:
        devDependencies: true
        src: '<%%= karma.unit.configFile %>'
        exclude: ['egemswatch', 'jquery', 'es5-shim', 'json3']
        ignorePath: /\.\.\//
        fileTypes:
          coffee:
            block: /(([\s\t]*)#\s*?bower:\s*?(\S*))(\n|\r|.)*?(#\s*endbower)/gi
            detect:
              js: /'(.*\.js)'/gi
              coffee: /'(.*\.coffee)'/gi
            replace:
              js: '\'{{filePath}}\''
              coffee: '\'{{filePath}}\''


    coffee:
      options:
        sourceMap: true
        sourceRoot: ''
      dist:
        files: [{
          expand: true
          cwd: '<%%= appConfig.src %>/scripts'
          src: '{,**/}*.coffee'
          dest: '.tmp/scripts'
          ext: '.js'
        }]
      test:
        files: [{
          expand: true
          cwd: 'web/test/spec'
          src: '{,**/}*.coffee'
          dest: '.tmp/spec'
          ext: '.js'
        }]


    filerev:
      dist:
        src: [
          '<%%= appConfig.dist %>/scripts/{,**/}*.js'
          '<%%= appConfig.dist %>/styles/{,**/}*.css'
          '<%%= appConfig.dist %>/images/{,**/}*.{png,jpg,jpeg,gif,webp,svg}'
          '<%%= appConfig.dist %>/fonts/*'
        ]


    useminPrepare:
      html: '<%%= appConfig.src %>/index.html'
      options:
        dest: '<%%= appConfig.dist %>'
        cwd: '<%%= appConfig.src %>'
        flow:
          html:
            steps:
              js: [
                'concat'
                'uglifyjs'
              ]
              css: ['cssmin']
            post: {}


    usemin:
      html: ['<%%= appConfig.dist %>/{,**/}*.html']
      css: ['<%%= appConfig.dist %>/styles/{,**/}*.css']
      options:
        assetsDirs: [
          '<%%= appConfig.dist %>'
          '<%%= appConfig.dist %>/images'
          '<%%= appConfig.dist %>/styles'
          '<%%= appConfig.dist %>/fonts'
        ]
    imagemin:
      dist:
        files: [{
          expand: true
          cwd: '<%%= appConfig.src %>/images'
          src: '{,**/}*.{png,jpg,jpeg,gif}'
          dest: '<%%= appConfig.dist %>/images'
        }]


    svgmin:
      dist:
        files: [{
          expand: true
          cwd: '<%%= appConfig.src %>/images'
          src: '{,**/}*.svg'
          dest: '<%%= appConfig.dist %>/images'
        }]


    htmlmin:
      dist:
        options:
          collapseWhitespace: true
          conservativeCollapse: true
          collapseBooleanAttributes: true
          removeCommentsFromCDATA: true
          removeOptionalTags: true
        files: [{
          expand: true
          cwd: '<%%= appConfig.dist %>'
          src: [
            '*.html'
            'views/{,**/}*.html'
          ]
          dest: '<%%= appConfig.dist %>'
        }]


    ngAnnotate:
      dist:
        files: [{
          expand: true
          cwd: '.tmp/concat/scripts'
          src: '*.js'
          dest: '.tmp/concat/scripts'
        }]

    ngtemplates:
      app:
        cwd: '<%%= appConfig.src %>'
        src: 'views/{,**/}*.html'
        dest: '.tmp/scripts/app.js'
        options:
          module: '<%%= appConfig.module %>'
          append: true
          htmlmin:
            collapseWhitespace: true
            collapseBooleanAttributes: true

    cdnify:
      dist:
        html: ['<%%= appConfig.dist %>/*.html']


    copy:
      dist:
        files: [
          {
            expand: true
            dot: true
            cwd: '<%%= appConfig.src %>'
            dest: '<%%= appConfig.dist %>'
            src: [
              '*.{ico,png,txt}'
              '.htaccess'
              '*.html'
              # ngtemplates compiles htmls with templatecache
              # 'views/{,*/}*.html'
              'images/{,**/}*.{webp}'
              'fonts/{,**/}*.*'
            ]
          }
          {
            expand: true
            cwd: '.tmp/images'
            dest: '<%%= appConfig.dist %>/images'
            src: ['generated/*']
          }
          {
          # glyphicon and font-awesome font files
            expand: true
            flatten: true
            cwd: 'web/bower_components'
            dest: '<%%= appConfig.dist %>/fonts'
            src: [
              'font-awesome/fonts/*'
              'egemswatch/fonts/*'
            ]
          }
        ]
      scripts:
        expand: true
        cwd: '<%%= appConfig.src %>/scripts'
        dest: '.tmp/scripts/'
        src: '{,**/}*.js'
      styles:
        expand: true
        cwd: '<%%= appConfig.src %>/styles'
        dest: '.tmp/styles/'
        src: '{,**/}*.css'


    concurrent:
      server: [
        'coffee:dist'
        'copy:styles'
        'copy:scripts'
      ]
      test: [
        'coffee'
        'copy:styles'
        'copy:scripts'
      ]
      dist: [
        'coffee'
        'copy:styles'
        'copy:scripts'
        'imagemin'
        'svgmin'
      ]


    karma:
      unit:
        configFile: 'web/test/karma.conf.coffee'
        singleRun: true


    ngdocs:
      options:
        dest: 'docs'
        html5Mode: false
        title: '<%%= appConfig.name %> Documentation'
      all: ['.tmp/scripts/{,**/}*.js']


  grunt.registerTask 'serve', 'Compile then start a connect web server', (target) ->
    if target == 'dist'
      return grunt.task.run [
        'build'
        'configureProxies:server'
        'connect:dist:keepalive'
      ]
    grunt.task.run [
      'clean:server'
      'wiredep'
      'concurrent:server'
      'autoprefixer:server'
      'configureProxies:server'
      'connect:livereload'
      'watch'
    ]
    return


  grunt.registerTask 'test', [
    'clean:server'
    'wiredep'
    'concurrent:test'
    'autoprefixer'
    'connect:test'
    'karma'
  ]


  grunt.registerTask 'build', [
    'clean:dist'
    'wiredep'
    'useminPrepare'
    'concurrent:dist'
    'ngtemplates'
    'autoprefixer'
    'concat'
    'ngAnnotate'
    'copy:dist'
    # 'cdnify'
    'cssmin'
    'uglify'
    'filerev'
    'usemin'
    'htmlmin'
  ]


  grunt.registerTask 'default', [
    'newer:jshint'
    'test'
    'build'
    'ngdocs'
  ]

  return
