// Copyright IBM Corp. 2016. All Rights Reserved.
// Node module: apiconnect-cli-apps
// US Government Users Restricted Rights - Use, duplication or disclosure
// restricted by GSA ADP Schedule Contract with IBM Corp.

'use strict';

var _ = require('lodash');
var archiver = require('archiver');
var debug = require('debug')('apiconnect-cli-apps:lib:build:pack');
var fmt = require('util').format;
var fs = require('fs');
var glob = require('glob');
var path = require('path');

module.exports = exports = pack;

var FILTER = filterize([
  '.git',
  'CVS',
  '.svn',
  '.hg',
  '.lock-wscript',
  /^\.wafpickle-[0-9]+$/,
  /^\..*\.swp$/,
  '.DS_Store',
  /^\._/,
]);

function pack(folder, dst, type, embedPackageDir, callback) {
  var archiveOptions = {};
  var outputStream = fs.createWriteStream(dst);

  switch (type) {
    case 'zip':
    case 'tar':
      break;
    case 'tgz':
      type = 'tar';
      archiveOptions.gzip = true;
      break;
    default:
      return callback(new Error(fmt('The --format %s is not supported.', type)));
  }

  glob(path.join('**', '*'), { cwd: folder, dot: true }, function(err, files) {
    if (err) {
      return callback(err);
    }
    files = _.reject(files, FILTER);

    var archive = archiver.create(type, archiveOptions);
    archive.on('error', function(err) {
      debug('error in zip/tgz stream', err);
      callback(err);
    });

    outputStream.on('close', function() {
      debug('closing zip/tgz stream');
      callback();
    });

    _.each(files, function(file) {
      var entryData = {
        name: embedPackageDir ? path.join('package', file) : file,
      };
      archive.file(path.resolve(folder, file), entryData);
    });
    archive.pipe(outputStream);
    archive.finalize();
  });
}

function filterize(patterns) {
  patterns = patterns.map(testable);
  return filter;
  function filter(entry) {
    var basename = path.basename(entry);
    return patterns.some(function(p) { return p.test(basename); });
  }
  function testable(pattern) {
    if (pattern instanceof RegExp) {
      return pattern;
    }
    return new RegExp('^' + pattern + '$');
  }
}
