'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.cropAndSaveFile = cropAndSaveFile;
exports.smartCropAndSaveFile = smartCropAndSaveFile;
exports.cropAndSaveFiles = cropAndSaveFiles;
exports.generateThumbnail = generateThumbnail;
exports.saveFile = saveFile;
exports.isValidMedia = isValidMedia;
exports.getMediaType = getMediaType;
exports.createMediaSlug = createMediaSlug;
exports.createMediaFolder = createMediaFolder;
exports.getThumbsList = getThumbsList;
exports.getAssociatedImageFileFromThumb = getAssociatedImageFileFromThumb;

var _childProcessPromise = require('child-process-promise');

var _childProcessPromise2 = _interopRequireDefault(_childProcessPromise);

var _mkdirp = require('mkdirp');

var _mkdirp2 = _interopRequireDefault(_mkdirp);

var _fsExtra = require('fs-extra');

var _fsExtra2 = _interopRequireDefault(_fsExtra);

var _limax = require('limax');

var _limax2 = _interopRequireDefault(_limax);

var _jimp = require('jimp');

var _jimp2 = _interopRequireDefault(_jimp);

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var _bluebird = require('bluebird');

var _ = require('../../');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function cropAndSaveFile(imageSize, file, newFile) {
  var p = new _bluebird.Promise(function (resolve) {
    _jimp2.default.read(file).then(function (lenna) {
      lenna.crop(0, 0, parseInt(imageSize[0]), parseInt(imageSize[1])).write(newFile);
    }).catch(function (err) {
      console.error(err);
    });
    resolve();
  });
  return p;
}

function smartCropAndSaveFile(imageSize, file, newFile) {
  var cmd = 'node node_modules/smartcrop-cli/smartcrop-cli.js --width ' + parseInt(imageSize[0]) + ' --height ' + parseInt(imageSize[1]) + ' ' + file + ' ' + newFile;
  var p = _childProcessPromise2.default.exec(cmd);
  return p;
}

function cropAndSaveFiles(images, file, resp) {
  var length = images.length;
  var cropedImage = 0;
  resp.thumbs = [];
  var p = new _bluebird.Promise(function (resolve) {
    for (var i = 0; i < length; i++) {
      var image = images[i];
      var ext = _path2.default.extname(file);
      var newFile = file.replace(ext, '_' + images[i] + ext);
      resp.thumbs.push({
        name: newFile.replace(_path2.default.join(_.config.root, _.config.publish.url), ''),
        size: image
      });
      smartCropAndSaveFile(image.split('x'), file, newFile).then(function (result) {
        if (result.stderr) {
          cropAndSaveFile(image.split('x'), file, newFile).then(function () {
            if (++cropedImage === length) {
              resolve(resp);
            }
          });
        } else if (++cropedImage === length) {
          resolve(resp);
        }
      }).catch(function (err) {
        console.log(err);
      });
    }
  });

  return p;
}

function generateThumbnail(file) {
  var ext = _path2.default.extname(file).toLowerCase();
  var thumbFileName = file.replace(ext, '_thumb' + ext);
  var thumbFileNameRelative = thumbFileName.replace(_path2.default.join(_.config.root, _.config.publish.url), '');
  var p = new _bluebird.Promise(function (resolve) {
    var cropThumb = smartCropAndSaveFile([250, 250], file, thumbFileName);
    cropThumb.then(function (result) {
      var stderr = result.stderr;
      if (stderr) {
        cropAndSaveFile([250, 250], file, thumbFileName).then(function () {
          resolve({ thumb: thumbFileNameRelative });
        });
      } else resolve({ thumb: thumbFileNameRelative });
    });
  });

  return p;
}

function saveFile(req) {
  var p = new _bluebird.Promise(function (resolve) {
    var resp = { success: 1 };
    var filePath;
    req.pipe(req.busboy);
    req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
      var ext = _path2.default.extname(filename).toLowerCase();
      var slug = createMediaSlug(filename, ext);
      var mediaType = getMediaType(ext);

      var folderFilePath = createMediaFolder(mediaType);
      var hasSentHeader = false;

      filePath = _path2.default.join(folderFilePath, slug);
      resp['filePath'] = _path2.default.join('/' + mediaType, slug);

      file.on('limit', function () {
        hasSentHeader = true;
        file.resume();
        resolve({ error: 1, response: 'file is too big' });
        return;
      });

      var isValid = isValidMedia(mimetype, ext);
      if (isValid.error) {
        hasSentHeader = true;
        file.resume();
        resolve({ error: 1, response: isValid.error });
        return;
      }

      var fstream = _fsExtra2.default.createWriteStream(filePath);
      fstream.on('finish', function () {
        if (hasSentHeader) return;

        resp = _.abeExtend.hooks.instance.trigger('afterSaveImage', resp, req);

        if (mediaType === 'image') {
          var thumbPromise = generateThumbnail(filePath);
          thumbPromise.then(function (thumbResp) {
            resp.thumbnail = thumbResp.thumb;
            if (req.query.input.indexOf('data-size') > -1) {
              var thumbsSizes = _.cmsData.regex.getAttr(req.query.input, 'data-size').split(',');
              cropAndSaveFiles(thumbsSizes, filePath, resp).then(function (resp) {
                resolve(resp);
              });
            } else resolve(resp);
          });
        } else {
          resolve(resp);
        }
      });
      file.pipe(fstream);
    });
  });

  return p;
}

function isValidMedia(mimetype, ext) {
  var allowedExtensions = _.config.upload.extensions;
  var allowedMimetypes = _.config.upload.mimetypes;

  var error = false;
  if (allowedMimetypes.indexOf(mimetype) < 0) error = 'unauthorized file';else if (allowedExtensions.indexOf(ext) < 0) error = 'not a valid asset';

  return { error: error };
}

function getMediaType(ext) {
  var type = 'document';

  if (/\.(jpg|jpeg|png|gif|svg)/.test(ext)) {
    type = 'image';
  } else if (/\.(mov|avi|mp4)/.test(ext)) {
    type = 'video';
  } else if (/\.(mp3|wav)/.test(ext)) {
    type = 'sound';
  }

  return type;
}

function createMediaSlug(filename, ext) {
  var filenameNoExt = _path2.default.basename(filename, ext);
  return (0, _limax2.default)(filenameNoExt, { separateNumbers: false }) + '-' + _.coreUtils.random.generateUniqueIdentifier(2) + ext;
}

function createMediaFolder(mediaType) {
  var folderWebPath = '/' + mediaType;
  folderWebPath = _.abeExtend.hooks.instance.trigger('beforeSaveImage', folderWebPath);
  var folderFilePath = _path2.default.join(_.config.root, _.config.publish.url, folderWebPath);
  _mkdirp2.default.sync(folderFilePath);

  return folderFilePath;
}

function getThumbsList() {
  var thumbsList = [];
  var pathToThumbs = _path2.default.join(_.config.root, _.config.publish.url, _.config.upload.image);
  var files = _.coreUtils.file.getFilesSync(pathToThumbs, true);
  Array.prototype.forEach.call(files, function (pathFile) {
    pathFile = pathFile.replace(_path2.default.join(_.config.root, _.config.publish.url), '');
    if (pathFile.indexOf('_thumb.') > -1) {
      thumbsList.push({
        originalFile: pathFile.replace('_thumb.', '.'),
        thumbFile: pathFile
      });
    }
  });

  return thumbsList;
}

function getAssociatedImageFileFromThumb(name) {
  var rexMatchImageName = /_(thumb|\d+x\d+)\./;
  name = _path2.default.join(_path2.default.sep, name);
  var originalName = _path2.default.join(_path2.default.sep, name.replace(rexMatchImageName, '.'));
  var imageList = {
    thumbFile: name,
    originalFile: originalName,
    thumbs: []
  };
  var pathThumb = name.split('/');
  pathThumb.pop();
  pathThumb = _path2.default.join(_.config.root, _.config.publish.url, pathThumb.join('/'));

  var files = _.coreUtils.file.getFilesSync(pathThumb, true);
  Array.prototype.forEach.call(files, function (pathFile) {
    pathFile = pathFile.replace(_path2.default.join(_.config.root, _.config.publish.url), '');
    if (pathFile !== originalName && pathFile !== name && pathFile.replace(rexMatchImageName, '.') === originalName) {
      imageList.thumbs.push(pathFile);
    }
  });

  return imageList;
}