// Generated by CoffeeScript 2.5.0
(function() {
  var Yaml, bulk, coffee, fs, path;

  Yaml = require("js-yaml");

  bulk = require("bulk-require");

  path = require("path");

  fs = require("fs");

  coffee = require("coffeescript");

  module.exports = function(additionalTypes = {}, ignoreMissing = false) {
    var ConfigTypes, Constructor, SCHEMA, key, loadFile, parse, unparse, value, yamlTypes;
    ConfigTypes = bulk(path.resolve(__dirname, 'config-types'), '*');
    for (key in additionalTypes) {
      value = additionalTypes[key];
      ConfigTypes[key] = value;
    }
    yamlTypes = (function() {
      var results;
      results = [];
      for (key in ConfigTypes) {
        Constructor = ConfigTypes[key];
        results.push((function(key, Constructor) {
          return new Yaml.Type("!" + key, {
            kind: 'mapping',
            construct: function(data) {
              return new Constructor(data);
            },
            predicate: function(obj) {
              return obj.constructor === Constructor;
            },
            represent: function(obj) {
              return obj.options;
            }
          });
        })(key, Constructor));
      }
      return results;
    })();
    yamlTypes.push(new Yaml.Type('!coffee', {
      kind: 'scalar',
      construct: function(sourceCode) {
        // note that we do *NOT* want sandboxing here. For once, it does not add any
        // security (if the config is compromised, basically all is lost anyway).
        // Also, using a sandbox will create separate definitions of global constructors
        // like e.g. Object, which in turn creates problems when checking things like
        // foobar instanceof Object.
        return coffee.eval(sourceCode); //, sandbox:require './sandbox'
      }
    }));
    SCHEMA = Yaml.Schema.create(Yaml.DEFAULT_SCHEMA, yamlTypes);
    loadFile = function(file) {
      var content, e;
      content = void 0;
      try {
        content = fs.readFileSync(file);
      } catch (error) {
        e = error;
        if (ignoreMissing && e.code === "ENOENT") {
          return null;
        } else {
          throw e;
        }
      }
      return parse(content);
    };
    parse = function(content) {
      return Yaml.safeLoad(content, {
        schema: SCHEMA
      });
    };
    unparse = function(obj) {
      return Yaml.dump(obj, {
        schema: SCHEMA
      });
    };
    loadFile.parse = parse;
    loadFile.unparse = unparse;
    return loadFile;
  };

}).call(this);
