'use strict';

var fs = require('./util/fs');
var manifest = require('./manifest');
var pack = require('./packer-pack');

var AdmZip = require('adm-zip');
var Promise = require('bluebird');
var path = require('path');

var UNKNOWN_LICENSE = 'Unknown License';

module.exports = build;

function build(cfg) {
  return Promise.props(cfg)
  .then(function (cfg) {

    if (!cfg.entry) {
      throw new Error("No entry specified");
    }

    if (!cfg.package) {
      cfg.package = getPackage(cfg);
    }

    if (!cfg.manifest) {
      cfg.manifest = getManifest(cfg);
    }

    if (!cfg.license) {
      cfg.license = getLicense(cfg);
    }

    return Promise.props(cfg);
  })
  .then(function (cfg) {

    cfg.packed = pack(cfg.entry, cfg);

    return Promise.props(cfg);
  })
  .then(function (cfg) {

    var titaniumManifest = cfg.package.titaniumManifest || {};

    var moduleid = titaniumManifest.moduleid || cfg.package.name;
    var version = cfg.package.version + (cfg.noDependencies ? '-bare' : '');
    var pkg = cfg.package;

    cfg.bundlename = moduleid + '.js';
    cfg.zipname = (moduleid + '-commonjs-' + version + '.zip').toLowerCase();
    cfg.internalPath = 'modules/commonjs/' + moduleid + '/' + version;

    pkg._nativeDependencies = cfg.packed.nativeDependencies;
    pkg.main = cfg.bundlename;

    var zip = new AdmZip();

    zip.addFileToModule = addFileToModule.bind(null, zip, cfg);
    zip.writeModule = writeModule.bind(null, zip, cfg);
    zip.writeBundle = writeBundle.bind(null, zip, cfg);

    zip.addFileToModule('/manifest', cfg.manifest);
    zip.addFileToModule('/package.json', JSON.stringify(cfg.package, null, 2));
    zip.addFileToModule('/' + cfg.bundlename, cfg.packed.source);
    zip.addFileToModule('/LICENSE', cfg.license);

    return zip;
  });
}

function addFileToModule(zip, cfg, filename, content, comment) {
  filename = cfg.internalPath + filename;
  content = Buffer.isBuffer(content) ? content : (new Buffer(content));
  return zip.addFile(filename, content, comment);
}

function writeBundle(zip, cfg, dir) {
  return fs.writeFile(
    path.resolve(dir, cfg.bundlename), cfg.packed.source, 'utf8');
}

function writeModule(zip, cfg, dir) {
  return fs.writeFile(path.resolve(dir, cfg.zipname), zip.toBuffer(), 'binary');
}

function getLicense(cfg) {
  return Promise.resolve(cfg.entry)
  .then(function (entry) {
    return fs.readFile(path.resolve(entry, 'LICENSE'), 'utf8');
  })
  .catch(isENOENT, function (err) {
    return UNKNOWN_LICENSE;
  });
}

function isENOENT(err) {
  return ((err.cause || err).code === 'ENOENT');
}

function getPackage(cfg) {
  return Promise.resolve(cfg.entry)
  .then(function (entry) {
    return fs.readFile(path.resolve(entry, 'package.json'), 'utf8');
  })
  .then(JSON.parse);
}

function getManifest(cfg) {
  return Promise.resolve(cfg.package)
  .then(manifest.validatePackage)
  .then(manifest.buildFromPackage);
}

@@ -1342,24 +1342,102 @@
  AdmZip();%0A%0A
+    zip.addLocalFolderToModule = addLocalFolderToModule.bind(null, zip, cfg);%0A
     zip.addF
@@ -1480,32 +1480,32 @@
 ull, zip, cfg);%0A
-
     zip.writeMod
@@ -1858,23 +1858,843 @@
     
-return zip;%0A  %7D
+var directories = pkg.directories %7C%7C %7B%7D;%0A%0A    var exampleDir = directories.example %7C%7C 'example';%0A    var documentationDir = directories.documentation %7C%7C 'documentation';%0A%0A    exampleDir = path.resolve(cfg.entry, exampleDir);%0A    documentationDir = path.resolve(cfg.entry, documentationDir);%0A%0A    return Promise.all(%5B%0A      fs.isDirectory(exampleDir),%0A      fs.isDirectory(documentationDir)%0A    %5D).spread(function (hasExample, hasDocumentation) %7B%0A      if (hasExample) %7B%0A        zip.addLocalFolderToModule(exampleDir, '/example');%0A      %7D%0A%0A      if (hasDocumentation) %7B%0A        zip.addLocalFolderToModule(documentationDir, '/documentation');%0A      %7D%0A%0A      return zip;%0A    %7D);%0A  %7D);%0A%7D%0A%0Afunction addLocalFolderToModule(zip, cfg, localPath, zipPath) %7B%0A  zipPath = cfg.internalPath + zipPath;%0A  return zip.addLocalFolder(localPath, zipPath
 );%0A%7D

Add example and documentation folders. Fixes #25