TaskManager = require 'uproxy-lib/tools/taskmanager'
Rule = require 'uproxy-lib/tools/common-grunt-rules'

Path = require('path');

uproxyLibPath = Path.dirname(require.resolve('uproxy-lib/package.json'))
utransformersPath = Path.dirname(require.resolve('utransformers/package.json'))
regex2dfaPath = Path.dirname(require.resolve('regex2dfa/package.json'))

FILES =
  # Help Jasmine's PhantomJS understand promises.
  jasmine_helpers: [
    'node_modules/es6-promise/dist/promise-*.js',
    '!node_modules/es6-promise/dist/promise-*amd.js',
    '!node_modules/es6-promise/dist/promise-*.min.js'
  ]

module.exports = (grunt) ->
  grunt.initConfig

    # TODO: Replace a common-grunt-rules function, when available.
    symlink:
      # Symlink each source file under src/ under build/.
      build:
        files: [
          expand: true
          cwd: 'src/'
          src: ['**/*']
          filter: 'isFile'
          dest: 'build/'
        ]

      # Symlink each file under uproxy-lib's dist/ under build/.
      # Exclude the samples/ directory.
      uproxyLibBuild:
        files: [
          expand: true
          cwd: Path.join(uproxyLibPath, 'dist/')
          src: ['**/*', '!samples/**']
          filter: 'isFile'
          dest: 'build/'
        ]

      # Symlink each directory under uproxy-lib's third_party/ under build/third_party/.
      uproxyLibThirdParty:
        files: [
          expand: true
          cwd: Path.join(uproxyLibPath, 'third_party/')
          src: ['*']
          filter: 'isDirectory'
          dest: 'build/third_party/'
        ]

      # Symlink each .d.ts and .js file under utransformers' src/ directory
      # under build/utransformers/.
      utransformers:
        files: [
          expand: true
          cwd: Path.join(utransformersPath, 'src/')
          src: ['**/*.d.ts', '**/*.js']
          dest: 'build/utransformers/'
        ]

      # There's only one relevant file in this repo: regex2dfa.js.
      regex2dfa:
        files: [
          expand: true
          cwd: regex2dfaPath
          src: ['**/*.js']
          dest: 'build/regex2dfa/'
        ]

    copy:
      sha1: Rule.copyModule 'sha1'
      turn: Rule.copyModule 'turn'
      net: Rule.copyModule 'net'
      utransformers: Rule.copyModule 'utransformers'
      regex2dfa: Rule.copyModule 'regex2dfa'
      transformers: Rule.copyModule 'transformers'
      pipe: Rule.copyModule 'pipe'
      churn: Rule.copyModule 'churn'

      simpleTurnChromeApp: Rule.copyModule 'samples/simple-turn-chromeapp'
      simpleTurnChromeAppLib: Rule.copySampleFiles 'samples/simple-turn-chromeapp'

      simpleChurnChatChromeApp: Rule.copyModule 'samples/simple-churn-chat-chromeapp'
      simpleChurnChatChromeAppLib: Rule.copySampleFiles 'samples/simple-churn-chat-chromeapp'

      copypasteChurnChatChromeApp: Rule.copyModule 'samples/copypaste-churn-chat-chromeapp'
      copypasteChurnChatChromeAppLib: Rule.copySampleFiles 'samples/copypaste-churn-chat-chromeapp'

    ts:
      turn: Rule.typescriptSrc 'turn'
      turnSpecDecl: Rule.typescriptSpecDecl 'turn'

      net: Rule.typescriptSrc 'net'

      transformers: Rule.typescriptSrc 'transformers'
      transformersSpecDecl: Rule.typescriptSpecDecl 'transformers'

      pipe: Rule.typescriptSrc 'pipe'

      churn: Rule.typescriptSrc 'churn'
      churnSpecDecl: Rule.typescriptSpecDecl 'churn'

      simpleTurnChromeApp: Rule.typescriptSrc 'samples/simple-turn-chromeapp'
      simpleChurnChatChromeApp: Rule.typescriptSrc 'samples/simple-churn-chat-chromeapp'

      copypasteTurnChromeApp: Rule.typescriptSrc 'samples/copypaste-turn-chromeapp'
      copypasteChurnChatChromeApp: Rule.typescriptSrc 'samples/copypaste-churn-chat-chromeapp'

    browserify:
      sha1:
        src: [require.resolve('crypto/sha1')]
        dest: 'build/sha1/sha1.js'
        options:
          browserifyOptions:
            standalone: 'sha1'

    jasmine:
      # TODO: turn tests require arraybuffers
      #       https://github.com/uProxy/uproxy/issues/430
      turn:
        src: FILES.jasmine_helpers.concat([
          'build/turn/mocks.js'
          'build/turn/messages.js'
          'build/turn/turn.js'
          'build/arraybuffers/arraybuffers.js'
          'build/sha1/sha1.js'
        ])
        options:
          specs: 'build/turn/*.spec.js'
      # TODO: churn tests require peerconnection
      #       https://github.com/uProxy/uproxy/issues/430
      churn:
        src: FILES.jasmine_helpers.concat([
          'build/churn/mocks.js'
          'build/churn/churn.js'
          'build/peerconnection/*.js'
        ]),
        options:
          specs: 'build/churn/*.spec.js'
      transformers: Rule.jasmineSpec 'transformers'

    clean: ['build/', 'dist/', '.tscache/']

  #-------------------------------------------------------------------------
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-ts');
  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-browserify');
  grunt.loadNpmTasks('grunt-contrib-symlink');

  #-------------------------------------------------------------------------
  # Define the tasks
  taskManager = new TaskManager.Manager();

  taskManager.add 'base', [
    'symlink:build'
    'symlink:uproxyLibBuild'
    'symlink:uproxyLibThirdParty'
    'symlink:utransformers'
    'symlink:regex2dfa'
  ]

  taskManager.add 'sha1', [
    'base'
    'browserify:sha1'
    'copy:sha1'
  ]

  taskManager.add 'turn', [
    'base'
    'sha1'
    'ts:turn'
    'ts:turnSpecDecl'
    'copy:turn'
  ]

  taskManager.add 'net', [
    'base'
    'ts:net'
    'copy:net'
  ]

  taskManager.add 'utransformers', [
    'base'
    'copy:utransformers'
    'copy:regex2dfa'
  ]

  taskManager.add 'transformers', [
    'base'
    'utransformers'
    'ts:transformers'
    'ts:transformersSpecDecl'
    'copy:transformers'
  ]

  taskManager.add 'pipe', [
    'base'
    'transformers'
    'ts:pipe'
    'copy:pipe'
  ]

  taskManager.add 'churn', [
    'base'
    'turn'
    'net'
    'pipe'
    'ts:churn'
    'ts:churnSpecDecl'
    'copy:churn'
  ]

  taskManager.add 'simpleTurnChromeApp', [
    'base'
    'turn'
    'net'
    'ts:simpleTurnChromeApp'
    'copy:simpleTurnChromeApp'
    'copy:simpleTurnChromeAppLib'
  ]

  taskManager.add 'simpleChurnChatChromeApp', [
    'base'
    'turn'
    'net'
    'ts:simpleChurnChatChromeApp'
    'copy:simpleChurnChatChromeApp'
    'copy:simpleChurnChatChromeAppLib'
  ]

  taskManager.add 'copypasteChurnChatChromeApp', [
    'base'
    'turn'
    'net'
    'ts:copypasteChurnChatChromeApp'
    'copy:copypasteChurnChatChromeApp'
    'copy:copypasteChurnChatChromeAppLib'
  ]

  taskManager.add 'samples', [
    'simpleTurnChromeApp'
    'simpleChurnChatChromeApp'
    'copypasteChurnChatChromeApp'
  ]

  taskManager.add('build', [
    'turn',
    'net',
    'transformers',
    'pipe',
    'churn',
    'samples',
  ]);

  taskManager.add('test', [
    'build',
    'jasmine'
  ]);

  taskManager.add('default', ['build']);

  taskManager.list().forEach((taskName) =>
    grunt.registerTask taskName, (taskManager.get taskName)
  );
