/* eslint-disable no-console */
import Async from 'neo-async';
import fs from 'fs';
import * as Handlebars from './handlebars';
import {basename} from 'path';
import {SourceMapConsumer, SourceNode} from 'source-map';


module.exports.loadTemplates = function(opts, callback) {
  loadStrings(opts, function(err, strings) {
    if (err) {
      callback(err);
    } else {
      loadFiles(opts, function(err, files) {
        if (err) {
          callback(err);
        } else {
          opts.templates = strings.concat(files);
          callback(undefined, opts);
        }
      });
    }
  });
};

function loadStrings(opts, callback) {
  let strings = arrayCast(opts.string),
      names = arrayCast(opts.name);

  if (names.length !== strings.length
      && strings.length > 1) {
    return callback(new Handlebars.Exception('Number of names did not match the number of string inputs'));
  }

  Async.map(strings, function(string, callback) {
      if (string !== '-') {
        callback(undefined, string);
      } else {
        // Load from stdin
        let buffer = '';
        process.stdin.setEncoding('utf8');

        process.stdin.on('data', function(chunk) {
          buffer += chunk;
        });
        process.stdin.on('end', function() {
          callback(undefined, buffer);
        });
      }
    },
    function(err, strings) {
      strings = strings.map((string, index) => ({
        name: names[index],
        path: names[index],
        source: string
      }));
      callback(err, strings);
    });
}

function loadFiles(opts, callback) {
  // Build file extension pattern
  let extension = (opts.extension || 'handlebars').replace(/[\\^$*+?.():=!|{}\-[\]]/g, function(arg) { return '\\' + arg; });
  extension = new RegExp('\\.' + extension + '$');

  let ret = [],
      queue = (opts.files || []).map((template) => ({template, root: opts.root}));
  Async.whilst(() => queue.length, function(callback) {
    let {template: path, root} = queue.shift();

    fs.stat(path, function(err, stat) {
      if (err) {
        return callback(new Handlebars.Exception(`Unable to open template file "${path}"`));
      }

      if (stat.isDirectory()) {
        opts.hasDirectory = true;

        fs.readdir(path, function(err, children) {
          /* istanbul ignore next : Race condition that being too lazy to test */
          if (err) {
            return callback(err);
          }
          children.forEach(function(file) {
            let childPath = path + '/' + file;

            if (extension.test(childPath) || fs.statSync(childPath).isDirectory()) {
              queue.push({template: childPath, root: root || path});
            }
          });

          callback();
        });
      } else {
        fs.readFile(path, 'utf8', function(err, data) {
          /* istanbul ignore next : Race condition that being too lazy to test */
          if (err) {
            return callback(err);
          }

          if (opts.bom && data.indexOf('\uFEFF') === 0) {
            data = data.substring(1);
          }

          // Clean the template name
          let name = path;
          if (!root) {
            name = basename(name);
          } else if (name.indexOf(root) === 0) {
            name = name.substring(root.length + 1);
          }
          name = name.replace(extension, '');

          ret.push({
            path: path,
            name: name,
            source: data
          });

          callback();
        });
      }
    });
  },
  function(err) {
    if (err) {
      callback(err);
    } else {
      callback(undefined, ret);
    }
  });
}

module.exports.cli = function(opts) {
  if (opts.version) {
    console.log(Handlebars.VERSION);
    return;
  }

  if (!opts.templates.length && !opts.hasDirectory) {
    throw new Handlebars.Exception('Must define at least one template or directory.');
  }

  if (opts.simple && opts.min) {
    throw new Handlebars.Exception('Unable to minimize simple output');
  }

  const multiple = opts.templates.length !== 1 || opts.hasDirectory;
  if (opts.simple && multiple) {
    throw new Handlebars.Exception('Unable to output multiple templates in simple mode');
  }

  // Force simple mode if we have only one template and it's unnamed.
  if (!opts.amd && !opts.commonjs && opts.templates.length === 1
      && !opts.templates[0].name) {
    opts.simple = true;
  }

  // Convert the known list into a hash
  let known = {};
  if (opts.known && !Array.isArray(opts.known)) {
    opts.known = [opts.known];
  }
  if (opts.known) {
    for (let i = 0, len = opts.known.length; i < len; i++) {
      known[opts.known[i]] = true;
    }
  }

  const objectName = opts.partial ? 'Handlebars.partials' : 'templates';

  let output = new SourceNode();
  if (!opts.simple) {
    if (opts.amd) {
      output.add('define([\'' + opts.handlebarPath + 'handlebars.runtime\'], function(Handlebars) {\n  Handlebars = Handlebars["default"];');
    } else if (opts.commonjs) {
      output.add('var Handlebars = require("' + opts.commonjs + '");');
    } else {
      output.add('(function() {\n');
    }
    output.add('  var template = Handlebars.template, templates = ');
    if (opts.namespace) {
      output.add(opts.namespace);
      output.add(' = ');
      output.add(opts.namespace);
      output.add(' || ');
    }
    output.add('{};\n');
  }

  opts.templates.forEach(function(template) {
    let options = {
      knownHelpers: known,
      knownHelpersOnly: opts.o
    };

    if (opts.map) {
      options.srcName = template.path;
    }
    if (opts.data) {
      options.data = true;
    }

    let precompiled = Handlebars.precompile(template.source, options);

    // If we are generating a source map, we have to reconstruct the SourceNode object
    if (opts.map) {
      let consumer = new SourceMapConsumer(precompiled.map);
      precompiled = SourceNode.fromStringWithSourceMap(precompiled.code, consumer);
    }

    if (opts.simple) {
      output.add([precompiled, '\n']);
    } else {
      if (!template.name) {
        throw new Handlebars.Exception('Name missing for template');
      }

      if (opts.amd && !multiple) {
        output.add('return ');
      }
      output.add([objectName, '[\'', template.name, '\'] = template(', precompiled, ');\n']);
    }
  });

  // Output the content
  if (!opts.simple) {
    if (opts.amd) {
      if (multiple) {
        output.add(['return ', objectName, ';\n']);
      }
      output.add('});');
    } else if (!opts.commonjs) {
      output.add('})();');
    }
  }

  if (opts.map) {
    output.add('\n//# sourceMappingURL=' + opts.map + '\n');
  }

  output = output.toStringWithSourceMap();
  output.map = output.map + '';

  if (opts.min) {
    output = minify(output, opts.map);
  }

  if (opts.map) {
    fs.writeFileSync(opts.map, output.map, 'utf8');
  }
  output = output.code;

  if (opts.output) {
    fs.writeFileSync(opts.output, output, 'utf8');
  } else {
    console.log(output);
  }
};

function arrayCast(value) {
  value = value != null ? value : [];
  if (!Array.isArray(value)) {
    value = [value];
  }
  return value;
}

/**
 * Run uglify to minify the compiled template, if uglify exists in the dependencies.
 *
 * We are using `require` instead of `import` here, because es6-modules do not allow
 * dynamic imports and uglify-js is an optional dependency. Since we are inside NodeJS here, this
 * should not be a problem.
 *
 * @param {string} output the compiled template
 * @param {string} sourceMapFile the file to write the source map to.
 */
function minify(output, sourceMapFile) {
  try {
    // Try to resolve uglify-js in order to see if it does exist
    require.resolve('uglify-js');
  } catch (e) {
    if (e.code !== 'MODULE_NOT_FOUND') {
      // Something else seems to be wrong
      throw e;
    }
    // it does not exist!
    console.error('Code minimization is disabled due to missing uglify-js dependency');
    return output;
  }
  return require('uglify-js').minify(output.code, {
    sourceMap: {
      content: output.map,
      url: sourceMapFile
    }
  });
}
