/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
module.exports = function(grunt) {
  'use strict';
  var config = {};

  config.pkg = grunt.file.readJSON('package.json');
  var xml = grunt.file.read('pom.xml').toString('UTF-8');
  var DOMParser = require('xmldom').DOMParser;
  var pom = new DOMParser().parseFromString(xml, 'text/xml');
  var versionElement = pom.documentElement.getElementsByTagName('version')[0];
  var version = versionElement.textContent;
  if (version.endsWith('SNAPSHOT')) {
    version += '.' + Date.now();
  }
  config.pkg.version = version;
  delete config.pkg.devDependencies;
  delete config.pkg.private;

  config.clean = {target: ['target']};

  config.compile = {
    config: ['Gruntfile.js', 'karma.conf.js', 'banner.js'],
    lib: ['lib/*.js'],
    spec: ['spec/*.js'],
    options: {jshintrc: true}
  };

  config.test = {
    options: {
      configFile: 'karma.conf.js',
      files: [
        'node_modules/node-forge/dist/forge.min.js',
        'node_modules/sjcl/sjcl.js',
        'lib/cryptolib.js',
        'lib/**/*.js',
        'spec/cryptolib.spec.js',
        'spec/proofs.service/proofs.service.spec.lib.js',
      ]
    },
    asymmetric: {
      files: [
        {src: ['spec/asymmetric*.spec.js'], served: true},
      ]
    },
    certificates: {
      files: [
        {src: ['spec/certificates*.spec.js'], served: true},
      ]
    },
    commons: {
      files: [
        {src: ['spec/commons*.spec.js'], served: true},
      ]
    },
    crypto: {
      files: [
        {src: ['spec/crypto*.spec.js'], served: true},
      ]
    },
    digitalenvelope: {
      files: [
        {src: ['spec/digitalenvelope*.spec.js'], served: true},
      ]
    },
    homomorphic: {
      files: [
        {src: ['spec/homomorphic*.spec.js'], served: true},
      ]
    },
    primitives: {
      files: [
        {src: ['spec/primitives*.spec.js'], served: true},
      ]
    },
    proofs: {
      files: [
        {src: ['spec/proofs.spec.js'], served: true},
      ]
    },
    proofs_service_exponentiation: {
      files: [
        {
          src: ['spec/proofs.service/proofs.service.exponentiation.spec.js'],
          served: true
        },
      ]
    },
    proofs_service_plaintext: {
      files: [
        {
          src: ['spec/proofs.service/proofs.service.plaintext.spec.js'],
          served: true
        },
      ]
    },
    proofs_service_plaintext_equality: {
      files: [
        {
          src:
              ['spec/proofs.service/proofs.service.plaintext_equality.spec.js'],
          served: true
        },
      ]
    },
    proofs_service_plaintext_exponent_equality: {
      files: [
        {
          src: [
            'spec/proofs.service/proofs.service.plaintext_exponent_equality.spec.js'
          ],
          served: true
        },
      ]
    },
    proofs_service_schnorr: {
      files: [
        {
          src: ['spec/proofs.service/proofs.service.schnorr.spec.js'],
          served: true
        },
      ]
    },
    proofs_service_simple_plaintext_equality: {
      files: [
        {
          src: [
            'spec/proofs.service/proofs.service.simple_plaintext_equality.spec.js'
          ],
          served: true
        },
      ]
    },
    proofs_service_or: {
      files: [
        {src: ['spec/proofs.service/proofs.service.or.spec.js'], served: true},
      ]
    },
    stores: {
      files: [
        {src: ['spec/stores*.spec.js'], served: true},
      ]
    },
    symmetric: {
      files: [
        {src: ['spec/symmetric*.spec.js'], served: true},
      ]
    }
  };

  var banner = grunt.file.read('banner.js').toString('UTF-8');

  config.concat = {
    all: {
      src: ['lib/cryptolib.js', 'lib/*.js'],
      dest: 'target/package/lib/<%= pkg.name %>.js'
    },
    options: {banner: banner}
  };

  config.uglify = {
    all: {
      files: {
        'target/package/lib/<%= pkg.name %>.min.js':
            ['target/package/lib/<%= pkg.name %>.js']
      }
    },
    options: {banner: banner}
  };

  config.copy = {
    all: {
      files: [
        {src: '*.md', dest: 'target/package/'},
        {src: 'vendor/*.js', dest: 'target/package/'}
      ]
    }
  };

  config.run = {
    pack: {exec: 'npm pack package/', options: {cwd: 'target'}},
    publish: {exec: 'npm publish --dd <%= pkg.name %>-<%= pkg.version %>.tgz', options: {cwd: 'target'}},
    format: {
      exec:
          'node node_modules/clang-format -style=Google -i lib/*.js spec/*.js spec/**/*.js Gruntfile.js karma.conf.js'
    }
  };

  grunt.initConfig(config);

  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-karma');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-run');

  grunt.renameTask('jshint', 'compile');

  grunt.renameTask('karma', 'test');

  grunt.registerTask('compose', function() {
    var json = JSON.stringify(config.pkg, null, 4);
    grunt.file.write('target/package/package.json', json);
  });

  grunt.registerTask(
      'package', ['compose', 'concat', 'uglify', 'copy', 'run:pack']);

  grunt.registerTask('deploy', ['package', 'run:publish']);

  grunt.registerTask('default', ['clean', 'compile', 'test', 'package']);

  grunt.registerTask('format', ['run:format']);
};
