// Generated by CoffeeScript 1.6.2
var ConsoleInterface, TaskGroup, balUtil, cliColor, extendr, pathUtil, safefs,
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  __slice = [].slice,
  __hasProp = {}.hasOwnProperty;

cliColor = require('cli-color');

pathUtil = require('path');

balUtil = require('bal-util');

safefs = require('safefs');

TaskGroup = require('taskgroup').TaskGroup;

extendr = require('extendr');

ConsoleInterface = (function() {
  function ConsoleInterface(opts, next) {
    this.watch = __bind(this.watch, this);
    this.skeleton = __bind(this.skeleton, this);
    this.clean = __bind(this.clean, this);
    this.server = __bind(this.server, this);
    this.run = __bind(this.run, this);
    this.render = __bind(this.render, this);
    this.install = __bind(this.install, this);
    this.info = __bind(this.info, this);
    this.help = __bind(this.help, this);
    this.generate = __bind(this.generate, this);
    this.action = __bind(this.action, this);
    this.welcomeCallback = __bind(this.welcomeCallback, this);
    this.selectSkeletonCallback = __bind(this.selectSkeletonCallback, this);
    this.extractConfig = __bind(this.extractConfig, this);
    this.completeAction = __bind(this.completeAction, this);
    this.performAction = __bind(this.performAction, this);
    this.handleError = __bind(this.handleError, this);
    this.getCommander = __bind(this.getCommander, this);
    this.start = __bind(this.start, this);
    var commander, consoleInterface, docpad, locale, version;

    consoleInterface = this;
    this.docpad = docpad = opts.docpad;
    this.commander = commander = require('commander');
    locale = docpad.getLocale();
    version = require(__dirname + '/../../../package.json').version;
    commander.version(version).option('-o, --out <outPath>', locale.consoleOptionOut).option('-c, --config <configPath>', locale.consoleOptionConfig).option('-e, --env <environment>', locale.consoleOptionEnv).option('-d, --debug [logLevel]', locale.consoleOptionDebug, parseInt).option('-f, --force', locale.consoleOptionForce).option('-p, --port <port>', locale.consoleOptionPort, parseInt).option('-s, --skeleton <skeleton>', locale.consoleOptionSkeleton);
    commander.command('action <actions>').description(locale.consoleDescriptionRun).action(consoleInterface.wrapAction(consoleInterface.action));
    commander.command('run').description(locale.consoleDescriptionRun).action(consoleInterface.wrapAction(consoleInterface.run));
    commander.command('server').description(locale.consoleDescriptionServer).action(consoleInterface.wrapAction(consoleInterface.server));
    commander.command('skeleton').description(locale.consoleDescriptionSkeleton).option('-s, --skeleton <skeleton>', locale.consoleOptionSkeleton).action(consoleInterface.wrapAction(consoleInterface.skeleton));
    commander.command('render [path]').description(locale.consoleDescriptionRender).action(consoleInterface.wrapAction(consoleInterface.render, {
      logLevel: 5,
      checkVersion: false,
      welcome: false,
      prompts: false
    }));
    commander.command('generate').description(locale.consoleDescriptionGenerate).action(consoleInterface.wrapAction(consoleInterface.generate));
    commander.command('watch').description(locale.consoleDescriptionWatch).action(consoleInterface.wrapAction(consoleInterface.watch));
    commander.command('install').description(locale.consoleDescriptionInstall).action(consoleInterface.wrapAction(consoleInterface.install));
    commander.command('clean').description(locale.consoleDescriptionClean).action(consoleInterface.wrapAction(consoleInterface.clean));
    commander.command('info').description(locale.consoleDescriptionInfo).action(consoleInterface.wrapAction(consoleInterface.info));
    commander.command('help').description(locale.consoleDescriptionHelp).action(consoleInterface.wrapAction(consoleInterface.help));
    commander.command('*').description(locale.consoleDescriptionUnknown).action(consoleInterface.wrapAction(consoleInterface.help));
    docpad.on('welcome', function(data, next) {
      return consoleInterface.welcomeCallback(data, next);
    });
    docpad.emitSync('consoleSetup', {
      consoleInterface: consoleInterface,
      commander: commander
    }, function(err) {
      if (err) {
        return consoleInterface.handleError(err);
      }
      return next(null, consoleInterface);
    });
    this;
  }

  ConsoleInterface.prototype.start = function(argv) {
    this.commander.parse(argv || process.argv);
    return this;
  };

  ConsoleInterface.prototype.getCommander = function() {
    return this.commander;
  };

  ConsoleInterface.prototype.handleError = function(err) {
    var docpad, locale;

    docpad = this.docpad;
    locale = docpad.getLocale();
    docpad.log('error', locale.consoleError);
    docpad.error(err);
    process.exit(1);
    return this;
  };

  ConsoleInterface.prototype.wrapAction = function(action, config) {
    var consoleInterface;

    consoleInterface = this;
    return function() {
      var args;

      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      return consoleInterface.performAction(action, args, config);
    };
  };

  ConsoleInterface.prototype.performAction = function(action, args, config) {
    var opts,
      _this = this;

    opts = {};
    opts.commander = args.slice(-1)[0];
    opts.args = args.slice(0, -1);
    opts.instanceConfig = extendr.safeDeepExtendPlainObjects({}, this.extractConfig(opts.commander), config);
    this.docpad.action('load ready', opts.instanceConfig, function(err) {
      if (err) {
        return _this.completeAction(err);
      }
      return action(_this.completeAction, opts);
    });
    return this;
  };

  ConsoleInterface.prototype.completeAction = function(err) {
    var docpad, locale;

    docpad = this.docpad;
    locale = docpad.getLocale();
    if (err) {
      this.handleError(err);
    } else {
      docpad.log('info', locale.consoleSuccess);
    }
    return this;
  };

  ConsoleInterface.prototype.extractConfig = function(customConfig) {
    var commanderConfig, config, configPath, key, outPath, sourceConfig, value;

    if (customConfig == null) {
      customConfig = {};
    }
    config = {};
    commanderConfig = this.commander;
    sourceConfig = this.docpad.initialConfig;
    if (commanderConfig.debug) {
      if (commanderConfig.debug === true) {
        commanderConfig.debug = 7;
      }
      commanderConfig.logLevel = commanderConfig.debug;
    }
    if (commanderConfig.config) {
      configPath = pathUtil.resolve(process.cwd(), commanderConfig.config);
      commanderConfig.configPaths = [configPath];
    }
    if (commanderConfig.out) {
      outPath = pathUtil.resolve(process.cwd(), commanderConfig.out);
      commanderConfig.outPath = outPath;
    }
    for (key in commanderConfig) {
      if (!__hasProp.call(commanderConfig, key)) continue;
      value = commanderConfig[key];
      if (typeof sourceConfig[key] !== 'undefined') {
        config[key] = value;
      }
    }
    for (key in customConfig) {
      if (!__hasProp.call(customConfig, key)) continue;
      value = customConfig[key];
      if (typeof sourceConfig[key] !== 'undefined') {
        config[key] = value;
      }
    }
    return config;
  };

  ConsoleInterface.prototype.selectSkeletonCallback = function(skeletonsCollection, next) {
    var commander, docpad, locale, skeletonNames;

    commander = this.commander;
    docpad = this.docpad;
    locale = docpad.getLocale();
    skeletonNames = [];
    console.log(cliColor.bold(locale.skeletonSelectionIntroduction + '\n'));
    skeletonsCollection.forEach(function(skeletonModel) {
      var skeletonDescription, skeletonName;

      skeletonName = skeletonModel.get('name');
      skeletonDescription = skeletonModel.get('description').replace(/\n/g, '\n\t');
      skeletonNames.push(skeletonName);
      return console.log("\t" + (cliColor.bold(skeletonName)) + "\n\t" + skeletonDescription + "\n");
    });
    console.log(cliColor.bold(locale.skeletonSelectionPrompt));
    commander.choose(skeletonNames, function(i) {
      process.stdin.destroy();
      return next(null, skeletonsCollection.at(i));
    });
    return this;
  };

  ConsoleInterface.prototype.welcomeCallback = function(opts, next) {
    var commander, consoleInterface, docpad, locale, userConfig, welcomeTasks;

    consoleInterface = this;
    commander = this.commander;
    docpad = this.docpad;
    locale = docpad.getLocale();
    userConfig = docpad.userConfig;
    welcomeTasks = new TaskGroup().once('complete', next);
    welcomeTasks.addTask(function(complete) {
      if (docpad.config.prompts === false || userConfig.tos === true) {
        return complete();
      }
      return consoleInterface.confirm(locale.tosPrompt, true, function(ok) {
        return docpad.track('tos', {
          ok: ok
        }, function(err) {
          if (ok) {
            userConfig.tos = true;
            console.log(locale.tosAgree);
            docpad.updateUserConfig(complete);
          } else {
            console.log(locale.tosDisagree);
            process.exit();
          }
        });
      });
    });
    welcomeTasks.addTask(function(complete) {
      if (docpad.config.prompts === false || (userConfig.subscribed != null) || ((userConfig.subscribeTryAgain != null) && (new Date()) > (new Date(userConfig.subscribeTryAgain)))) {
        return complete();
      }
      return consoleInterface.confirm(locale.subscribePrompt, true, function(ok) {
        return docpad.track('subscribe', {
          ok: ok
        }, function(err) {
          var commands;

          if (!ok) {
            console.log(locale.subscribeIgnore);
            userConfig.subscribed = false;
            docpad.updateUserConfig(function(err) {
              if (err) {
                return complete(err);
              }
              return balUtil.wait(2000, complete);
            });
            return;
          }
          commands = [['config', '--get', 'user.name'], ['config', '--get', 'user.email'], ['config', '--get', 'github.user']];
          return balUtil.spawnCommands('git', commands, function(err, results) {
            var subscribeTasks, _ref, _ref1, _ref2;

            userConfig.name || (userConfig.name = String((results != null ? (_ref = results[0]) != null ? _ref[1] : void 0 : void 0) || '').trim() || null);
            userConfig.email || (userConfig.email = String((results != null ? (_ref1 = results[1]) != null ? _ref1[1] : void 0 : void 0) || '').trim() || null);
            userConfig.username || (userConfig.username = String((results != null ? (_ref2 = results[2]) != null ? _ref2[1] : void 0 : void 0) || '').trim() || null);
            if (userConfig.name || userConfig.email || userConfig.username) {
              console.log(locale.subscribeConfigNotify);
            }
            subscribeTasks = new TaskGroup().once('complete', function(err) {
              if (err) {
                console.log(locale.subscribeError);
                userConfig.subscribeTryAgain = new Date().getTime() + 1000 * 60 * 60 * 24;
              } else {
                console.log(locale.subscribeSuccess);
                userConfig.subscribed = true;
                userConfig.subscribeTryAgain = null;
              }
              return docpad.updateUserConfig(userConfig, complete);
            });
            subscribeTasks.addTask(function(complete) {
              return consoleInterface.prompt(locale.subscribeNamePrompt, userConfig.name, function(result) {
                userConfig.name = result;
                return complete();
              });
            });
            subscribeTasks.addTask(function(complete) {
              return consoleInterface.prompt(locale.subscribeEmailPrompt, userConfig.email, function(result) {
                userConfig.email = result;
                return complete();
              });
            });
            subscribeTasks.addTask(function(complete) {
              return consoleInterface.prompt(locale.subscribeUsernamePrompt, userConfig.username, function(result) {
                userConfig.username = result;
                return complete();
              });
            });
            subscribeTasks.addTask(function(complete) {
              return docpad.updateUserConfig(complete);
            });
            subscribeTasks.addTask(function(complete) {
              var requestUrl;

              console.log(locale.subscribeProgress);
              requestUrl = docpad.config.helperUrl + '?' + require('querystring').stringify({
                method: 'add-subscriber',
                name: userConfig.name,
                email: userConfig.email,
                username: userConfig.username
              });
              return balUtil.readPath(requestUrl, function(err, body) {
                var data;

                if (err) {
                  docpad.log('debug', locale.subscribeRequestError, err.message);
                  return complete(err);
                }
                docpad.log('debug', locale.subscribeRequestData, body);
                try {
                  data = JSON.parse(body);
                  if (data.success === false) {
                    return complete(new Error(data.error || 'unknown error'));
                  } else {
                    return complete();
                  }
                } catch (_error) {
                  err = _error;
                  return complete(err);
                }
              });
            });
            return subscribeTasks.run();
          });
        });
      });
    });
    welcomeTasks.run();
    return this;
  };

  ConsoleInterface.prototype.prompt = function(message, fallback, next) {
    var commander, consoleInterface;

    consoleInterface = this;
    commander = this.commander;
    if (fallback) {
      message += " [" + fallback + "]";
    }
    commander.prompt(message + ' ', function(result) {
      if (!result.trim()) {
        if (fallback != null) {
          result = fallback;
        } else {
          return consoleInterface.prompt(message, fallback, next);
        }
      }
      return next(result);
    });
    return this;
  };

  ConsoleInterface.prototype.confirm = function(message, fallback, next) {
    var commander, consoleInterface;

    consoleInterface = this;
    commander = this.commander;
    if (fallback === true) {
      message += " [Y/n]";
    } else if (fallback === false) {
      message += " [y/N]";
    }
    commander.prompt(message + ' ', function(ok) {
      if (!ok.trim()) {
        if (fallback != null) {
          ok = fallback;
        } else {
          return consoleInterface.confirm(message, fallback, next);
        }
      } else {
        ok = /^y|yes|ok|true$/i.test(ok);
      }
      return next(ok);
    });
    return this;
  };

  ConsoleInterface.prototype.action = function(next, opts) {
    var actions;

    actions = opts.args[0];
    this.docpad.log('info', 'Performing the actions:', actions);
    this.docpad.action(actions, next);
    return this;
  };

  ConsoleInterface.prototype.generate = function(next) {
    this.docpad.action('generate', next);
    return this;
  };

  ConsoleInterface.prototype.help = function(next) {
    var help;

    help = this.commander.helpInformation();
    console.log(help);
    next();
    return this;
  };

  ConsoleInterface.prototype.info = function(next) {
    var info;

    info = require('util').inspect(this.docpad.config);
    console.log(info);
    next();
    return this;
  };

  ConsoleInterface.prototype.install = function(next) {
    this.docpad.action('install', next);
    return this;
  };

  ConsoleInterface.prototype.render = function(next, opts) {
    var basename, commander, data, docpad, filename, renderDocument, renderOpts, stdin, timeout, useStdin;

    docpad = this.docpad;
    commander = this.commander;
    renderOpts = {};
    filename = opts.args[0] || null;
    basename = pathUtil.basename(filename);
    renderOpts.filename = filename;
    renderOpts.renderSingleExtensions = 'auto';
    data = '';
    useStdin = true;
    renderDocument = function() {
      return docpad.action('render', renderOpts, function(err, result) {
        if (err) {
          return docpad.fatal(err);
        }
        if (commander.out != null) {
          return safefs.writeFile(commander.out, result, next);
        } else {
          process.stdout.write(result);
          return next();
        }
      });
    };
    timeout = setTimeout(function() {
      timeout = null;
      if (data.replace(/\s+/, '')) {
        return;
      }
      useStdin = false;
      stdin.pause();
      return renderDocument();
    }, 1000);
    stdin = process.stdin;
    stdin.resume();
    stdin.setEncoding('utf8');
    stdin.on('data', function(_data) {
      return data += _data.toString();
    });
    process.stdin.on('end', function() {
      if (!useStdin) {
        return;
      }
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      renderOpts.data = data;
      return renderDocument();
    });
    return this;
  };

  ConsoleInterface.prototype.run = function(next) {
    this.docpad.action('run', {
      selectSkeletonCallback: this.selectSkeletonCallback
    }, next);
    return this;
  };

  ConsoleInterface.prototype.server = function(next) {
    this.docpad.action('server generate', next);
    return this;
  };

  ConsoleInterface.prototype.clean = function(next) {
    this.docpad.action('clean', next);
    return this;
  };

  ConsoleInterface.prototype.skeleton = function(next) {
    this.docpad.action('skeleton', {
      selectSkeletonCallback: this.selectSkeletonCallback
    }, next);
    return this;
  };

  ConsoleInterface.prototype.watch = function(next) {
    this.docpad.action('generate watch', next);
    return this;
  };

  return ConsoleInterface;

})();

module.exports = ConsoleInterface;