"use strict";

/**
 * Update devDependencies module to archetype base script.
 */
var path = require("path");
var async = require("async");
var fs = require("fs-extra");

var tryRequire = function (filePath) {
  var resolved = path.resolve(filePath);
  try {
    /*eslint-disable global-require*/
    return require(resolved);
  } catch (err) {
    throw new Error("Unable to import: " + resolved + " with error:\n" + err.message);
  }
};

var ensureDevPackage = function (filePath) {
  var devPkg;
  if (fs.existsSync(filePath)) {
    devPkg = tryRequire(filePath);
  } else {
    var devDirPath = path.resolve("dev");
    if (!fs.existsSync(devDirPath)) {
      fs.mkdirSync(devDirPath);
    }
    devPkg = {dependencies: {}};
  }
  return devPkg;
};

/**
 * Update `target` JSON structure with fields from `source`.
 *
 * @param {Object} source Source JSON object
 * @param {Object} target Target JSON object
 * @returns {Object}      Updated JSON object
 */
var updatePkg = function (source, target) {
  // Clone source
  var pkg = JSON.parse(JSON.stringify(source));

  // Validation
  ["name", "description"].forEach(function (name) {
    if (!pkg[name]) {
      throw new Error("Source object missing field: " + name);
    }
  });

  if (!target.dependencies) {
    throw new Error("Target object missing field: dependencies");
  }

  // Update with "development" names
  pkg.name += "-dev";
  pkg.description += " (Development)";

  // Copy back in `dependencies` from dev package
  pkg.dependencies = target.dependencies;

  // Remove scripts, dev deps, etc.
  pkg.scripts = {};
  pkg.devDependencies = {};

  return pkg;
};

// Run the dev script.
module.exports = function (callback) {
  var prodPkg = tryRequire("package.json");
  var devPath = path.resolve("dev/package.json");
  var devPkg = ensureDevPackage(devPath);
  var updatedDevPkg = updatePkg(prodPkg, devPkg);

  async.parallel({
    package: function (cb) {
      fs.writeFile(devPath, JSON.stringify(updatedDevPkg, null, 2), cb);
    },
    gitignore: function (cb) {
      fs.copy(
        path.resolve(".gitignore"),
        path.resolve("dev/.gitignore"),
        cb
      );
    },
    readme: function (cb) {
      fs.copy(
        path.resolve("README.md"),
        path.resolve("dev/README.md"),
        cb
      );
    }
  }, callback);
};

@@ -437,322 +437,8 @@
 %7D;%0A%0A
-var ensureDevPackage = function (filePath) %7B%0A  var devPkg;%0A  if (fs.existsSync(filePath)) %7B%0A    devPkg = tryRequire(filePath);%0A  %7D else %7B%0A    var devDirPath = path.resolve(%22dev%22);%0A    if (!fs.existsSync(devDirPath)) %7B%0A      fs.mkdirSync(devDirPath);%0A    %7D%0A    devPkg = %7Bdependencies: %7B%7D%7D;%0A  %7D%0A  return devPkg;%0A%7D;%0A%0A
 /**%0A
@@ -767,16 +767,35 @@
 lidation
+ of source package.
 %0A  %5B%22nam
@@ -941,109 +941,8 @@
 );%0A%0A
-  if (!target.dependencies) %7B%0A    throw new Error(%22Target object missing field: dependencies%22);%0A  %7D%0A%0A
   //
@@ -1107,22 +1107,30 @@
 ncies = 
+(
 target
+ %7C%7C %7B%7D)
 .depende
@@ -1134,16 +1134,22 @@
 ndencies
+ %7C%7C %7B%7D
 ;%0A%0A  // 
@@ -1406,132 +1406,374 @@
 %22);%0A
+%0A
   
-var devPkg = ensureDevPackag
+async.auto(%7B%0A    ensureDevDirectory: fs.ensureDir.bind(fs, path.resolv
 e(
+%22
 dev
-Path);%0A  var updatedDevPkg = updatePkg(prodPkg, devPkg);%0A%0A  async.parallel(%7B%0A    p
+%22)),%0A%0A    readDevPackage: function (cb) %7B%0A      var devPkg = %7B%7D;%0A      try %7B%0A        devPkg = tryRequire(devPath);%0A      %7D catch (err) %7B%0A        // Ignore error and use default values.%0A      %7D%0A%0A      cb(null, devPkg);%0A    %7D,%0A%0A    writeDevPackage: %5B%22ensureDevDirectory%22, %22readDevP
 ackage
-:
+%22,
  fun
@@ -1773,36 +1773,115 @@
 e%22, function (cb
+, results
 ) %7B%0A
+      var updatedDevPkg = updatePkg(prodPkg, results.readDevPackage);%0A
       fs.writeFi
@@ -1946,15 +1946,22 @@
    %7D
-,
+%5D,%0A
 %0A    
-g
+writeG
 itig
@@ -1965,16 +1965,39 @@
 tignore:
+ %5B%22ensureDevDirectory%22,
  functio
@@ -2125,21 +2125,51 @@
    %7D
-,
+%5D,%0A
 %0A    
-readme:
+writeReadme: %5B%22ensureDevDirectory%22,
  fun
@@ -2291,24 +2291,25 @@
     );%0A    %7D
+%5D
 %0A  %7D, callba

Switch to async workflow.