'use strict';


var YAMLException = require('./exception');


var TYPE_CONSTRUCTOR_OPTIONS = [
  'loadKind',
  'loadResolver',
  'dumpInstanceOf',
  'dumpPredicate',
  'dumpRepresenter',
  'dumpDefaultStyle',
  'dumpStyleAliases'
];


var YAML_NODE_KINDS = [
  'scalar',
  'sequence',
  'mapping'
];


function compileStyleAliases(map) {
  var result = {};

  if (null !== map) {
    Object.keys(map).forEach(function (style) {
      map[style].forEach(function (alias) {
        result[String(alias)] = style;
      });
    });
  }

  return result;
}


function Type(tag, options) {
  options = options || {};

  Object.keys(options).forEach(function (name) {
    if (-1 === TYPE_CONSTRUCTOR_OPTIONS.indexOf(name)) {
      throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.');
    }
  });

  // TODO: Add tag format check.
  this.tag              = tag;
  this.loadKind         = options['loadKind']         || null;
  this.loadResolver     = options['loadResolver']     || null;
  this.dumpInstanceOf   = options['dumpInstanceOf']   || null;
  this.dumpPredicate    = options['dumpPredicate']    || null;
  this.dumpRepresenter  = options['dumpRepresenter']  || null;
  this.dumpDefaultStyle = options['dumpDefaultStyle'] || null;
  this.dumpStyleAliases = compileStyleAliases(options['dumpStyleAliases'] || null);

  if (-1 === YAML_NODE_KINDS.indexOf(this.loadKind)) {
    throw new YAMLException('Unknown loadKind "' + this.loadKind + '" is specified for "' + tag + '" YAML type.');
  }
}


module.exports = Type;
