'use strict';

/*eslint-disable no-use-before-define*/

var common              = require('./common');
var YAMLException       = require('./exception');
var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');

var _toString       = Object.prototype.toString;
var _hasOwnProperty = Object.prototype.hasOwnProperty;

var CHAR_TAB                  = 0x09; /* Tab */
var CHAR_LINE_FEED            = 0x0A; /* LF */
var CHAR_CARRIAGE_RETURN      = 0x0D; /* CR */
var CHAR_SPACE                = 0x20; /* Space */
var CHAR_EXCLAMATION          = 0x21; /* ! */
var CHAR_DOUBLE_QUOTE         = 0x22; /* " */
var CHAR_SHARP                = 0x23; /* # */
var CHAR_PERCENT              = 0x25; /* % */
var CHAR_AMPERSAND            = 0x26; /* & */
var CHAR_SINGLE_QUOTE         = 0x27; /* ' */
var CHAR_ASTERISK             = 0x2A; /* * */
var CHAR_COMMA                = 0x2C; /* , */
var CHAR_MINUS                = 0x2D; /* - */
var CHAR_COLON                = 0x3A; /* : */
var CHAR_GREATER_THAN         = 0x3E; /* > */
var CHAR_QUESTION             = 0x3F; /* ? */
var CHAR_COMMERCIAL_AT        = 0x40; /* @ */
var CHAR_LEFT_SQUARE_BRACKET  = 0x5B; /* [ */
var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */
var CHAR_GRAVE_ACCENT         = 0x60; /* ` */
var CHAR_LEFT_CURLY_BRACKET   = 0x7B; /* { */
var CHAR_VERTICAL_LINE        = 0x7C; /* | */
var CHAR_RIGHT_CURLY_BRACKET  = 0x7D; /* } */

var ESCAPE_SEQUENCES = {};

ESCAPE_SEQUENCES[0x00]   = '\\0';
ESCAPE_SEQUENCES[0x07]   = '\\a';
ESCAPE_SEQUENCES[0x08]   = '\\b';
ESCAPE_SEQUENCES[0x09]   = '\\t';
ESCAPE_SEQUENCES[0x0A]   = '\\n';
ESCAPE_SEQUENCES[0x0B]   = '\\v';
ESCAPE_SEQUENCES[0x0C]   = '\\f';
ESCAPE_SEQUENCES[0x0D]   = '\\r';
ESCAPE_SEQUENCES[0x1B]   = '\\e';
ESCAPE_SEQUENCES[0x22]   = '\\"';
ESCAPE_SEQUENCES[0x5C]   = '\\\\';
ESCAPE_SEQUENCES[0x85]   = '\\N';
ESCAPE_SEQUENCES[0xA0]   = '\\_';
ESCAPE_SEQUENCES[0x2028] = '\\L';
ESCAPE_SEQUENCES[0x2029] = '\\P';

var DEPRECATED_BOOLEANS_SYNTAX = [
  'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',
  'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'
];

function compileStyleMap(schema, map) {
  var result, keys, index, length, tag, style, type;

  if (map === null) return {};

  result = {};
  keys = Object.keys(map);

  for (index = 0, length = keys.length; index < length; index += 1) {
    tag = keys[index];
    style = String(map[tag]);

    if (tag.slice(0, 2) === '!!') {
      tag = 'tag:yaml.org,2002:' + tag.slice(2);
    }

    type = schema.compiledTypeMap[tag];

    if (type && _hasOwnProperty.call(type.styleAliases, style)) {
      style = type.styleAliases[style];
    }

    result[tag] = style;
  }

  return result;
}

function encodeHex(character) {
  var string, handle, length;

  string = character.toString(16).toUpperCase();

  if (character <= 0xFF) {
    handle = 'x';
    length = 2;
  } else if (character <= 0xFFFF) {
    handle = 'u';
    length = 4;
  } else if (character <= 0xFFFFFFFF) {
    handle = 'U';
    length = 8;
  } else {
    throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF');
  }

  return '\\' + handle + common.repeat('0', length - string.length) + string;
}

function State(options) {
  this.schema       = options['schema'] || DEFAULT_FULL_SCHEMA;
  this.indent       = Math.max(1, (options['indent'] || 2));
  this.skipInvalid  = options['skipInvalid'] || false;
  this.flowLevel    = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);
  this.styleMap     = compileStyleMap(this.schema, options['styles'] || null);
  this.sortKeys     = options['sortKeys'] || false;
  this.lineWidth    = options['lineWidth'] || 80;
  this.noRefs       = options['noRefs'] || false;
  this.noCompatMode = options['noCompatMode'] || false;

  this.implicitTypes = this.schema.compiledImplicit;
  this.explicitTypes = this.schema.compiledExplicit;

  this.tag = null;
  this.result = '';

  this.duplicates = [];
  this.usedDuplicates = null;
}

function indentString(string, spaces) {
  var ind = common.repeat(' ', spaces),
      position = 0,
      next = -1,
      result = '',
      line,
      length = string.length;

  while (position < length) {
    next = string.indexOf('\n', position);
    if (next === -1) {
      line = string.slice(position);
      position = length;
    } else {
      line = string.slice(position, next + 1);
      position = next + 1;
    }

    if (line.length && line !== '\n') result += ind;

    result += line;
  }

  return result;
}

function generateNextLine(state, level) {
  return '\n' + common.repeat(' ', state.indent * level);
}

function testImplicitResolving(state, str) {
  var index, length, type;

  for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {
    type = state.implicitTypes[index];

    if (type.resolve(str)) {
      return true;
    }
  }

  return false;
}

function StringBuilder(source) {
  this.source = source;
  this.result = '';
  this.checkpoint = 0;
}

StringBuilder.prototype.takeUpTo = function (position) {
  var er;

  if (position < this.checkpoint) {
    er = new Error('position should be > checkpoint');
    er.position = position;
    er.checkpoint = this.checkpoint;
    throw er;
  }

  this.result += this.source.slice(this.checkpoint, position);
  this.checkpoint = position;
  return this;
};

StringBuilder.prototype.escapeChar = function () {
  var character, esc;

  character = this.source.charCodeAt(this.checkpoint);
  esc = ESCAPE_SEQUENCES[character] || encodeHex(character);
  this.result += esc;
  this.checkpoint += 1;

  return this;
};

StringBuilder.prototype.finish = function () {
  if (this.source.length > this.checkpoint) {
    this.takeUpTo(this.source.length);
  }
};

function writeScalar(state, object, level, iskey) {
  var simple, first, spaceWrap, folded, literal, single, double,
      sawLineFeed, linePosition, longestLine, indent, max, character,
      position, escapeSeq, hexEsc, previous, lineLength, modifier,
      trailingLineBreaks, result;

  if (object.length === 0) {
    state.dump = "''";
    return;
  }

  if (!state.noCompatMode &&
      DEPRECATED_BOOLEANS_SYNTAX.indexOf(object) !== -1) {
    state.dump = "'" + object + "'";
    return;
  }

  simple = true;
  first = object.length ? object.charCodeAt(0) : 0;
  spaceWrap = (CHAR_SPACE === first ||
               CHAR_SPACE === object.charCodeAt(object.length - 1));

  // Simplified check for restricted first characters
  // http://www.yaml.org/spec/1.2/spec.html#ns-plain-first%28c%29
  if (CHAR_MINUS         === first ||
      CHAR_QUESTION      === first ||
      CHAR_COMMERCIAL_AT === first ||
      CHAR_GRAVE_ACCENT  === first) {
    simple = false;
  }

  // Can only use > and | if not wrapped in spaces or is not a key.
  // Also, don't use if in flow mode.
  if (spaceWrap || (state.flowLevel > -1 && state.flowLevel <= level)) {
    if (spaceWrap) simple = false;

    folded = false;
    literal = false;
  } else {
    folded = !iskey;
    literal = !iskey;
  }

  single = true;
  double = new StringBuilder(object);

  sawLineFeed = false;
  linePosition = 0;
  longestLine = 0;

  indent = state.indent * level;
  max = state.lineWidth;

  // Replace -1 with biggest ingeger number according to
  // http://ecma262-5.com/ELS5_HTML.htm#Section_8.5
  if (max === -1) max = 9007199254740991;

  if (indent < 40) max -= indent;
  else max = 40;

  for (position = 0; position < object.length; position++) {
    character = object.charCodeAt(position);
    if (simple) {
      // Characters that can never appear in the simple scalar
      if (!simpleChar(character)) {
        simple = false;
      } else {
        // Still simple.  If we make it all the way through like
        // this, then we can just dump the string as-is.
        continue;
      }
    }

    if (single && character === CHAR_SINGLE_QUOTE) {
      single = false;
    }

    escapeSeq = ESCAPE_SEQUENCES[character];
    hexEsc = needsHexEscape(character);

    if (!escapeSeq && !hexEsc) {
      continue;
    }

    if (character !== CHAR_LINE_FEED &&
        character !== CHAR_DOUBLE_QUOTE &&
        character !== CHAR_SINGLE_QUOTE) {
      folded = false;
      literal = false;
    } else if (character === CHAR_LINE_FEED) {
      sawLineFeed = true;
      single = false;
      if (position > 0) {
        previous = object.charCodeAt(position - 1);
        if (previous === CHAR_SPACE) {
          literal = false;
          folded = false;
        }
      }
      if (folded) {
        lineLength = position - linePosition;
        linePosition = position;
        if (lineLength > longestLine) longestLine = lineLength;
      }
    }

    if (character !== CHAR_DOUBLE_QUOTE) single = false;

    double.takeUpTo(position);
    double.escapeChar();
  }

  if (simple && testImplicitResolving(state, object)) simple = false;

  modifier = '';
  if (folded || literal) {
    trailingLineBreaks = 0;
    if (object.charCodeAt(object.length - 1) === CHAR_LINE_FEED) {
      trailingLineBreaks += 1;
      if (object.charCodeAt(object.length - 2) === CHAR_LINE_FEED) {
        trailingLineBreaks += 1;
      }
    }

    if (trailingLineBreaks === 0) modifier = '-';
    else if (trailingLineBreaks === 2) modifier = '+';
  }

  if (literal && longestLine < max || state.tag !== null) {
    folded = false;
  }

  // If it's literally one line, then don't bother with the literal.
  // We may still want to do a fold, though, if it's a super long line.
  if (!sawLineFeed) literal = false;

  if (simple) {
    state.dump = object;
  } else if (single) {
    state.dump = '\'' + object + '\'';
  } else if (folded) {
    result = fold(object, max);
    state.dump = '>' + modifier + '\n' + indentString(result, indent);
  } else if (literal) {
    if (!modifier) object = object.replace(/\n$/, '');
    state.dump = '|' + modifier + '\n' + indentString(object, indent);
  } else if (double) {
    double.finish();
    state.dump = '"' + double.result + '"';
  } else {
    throw new Error('Failed to dump scalar value');
  }

  return;
}

// The `trailing` var is a regexp match of any trailing `\n` characters.
//
// There are three cases we care about:
//
// 1. One trailing `\n` on the string.  Just use `|` or `>`.
//    This is the assumed default. (trailing = null)
// 2. No trailing `\n` on the string.  Use `|-` or `>-` to "chomp" the end.
// 3. More than one trailing `\n` on the string.  Use `|+` or `>+`.
//
// In the case of `>+`, these line breaks are *not* doubled (like the line
// breaks within the string), so it's important to only end with the exact
// same number as we started.
function fold(object, max) {
  var result = '',
      position = 0,
      length = object.length,
      trailing = /\n+$/.exec(object),
      newLine;

  if (trailing) {
    length = trailing.index + 1;
  }

  while (position < length) {
    newLine = object.indexOf('\n', position);
    if (newLine > length || newLine === -1) {
      if (result) result += '\n\n';
      result += foldLine(object.slice(position, length), max);
      position = length;

    } else {
      if (result) result += '\n\n';
      result += foldLine(object.slice(position, newLine), max);
      position = newLine + 1;
    }
  }

  if (trailing && trailing[0] !== '\n') result += trailing[0];

  return result;
}

function foldLine(line, max) {
  if (line === '') return line;

  var foldRe = /[^\s] [^\s]/g,
      result = '',
      prevMatch = 0,
      foldStart = 0,
      match = foldRe.exec(line),
      index,
      foldEnd,
      folded;

  while (match) {
    index = match.index;

    // when we cross the max len, if the previous match would've
    // been ok, use that one, and carry on.  If there was no previous
    // match on this fold section, then just have a long line.
    if (index - foldStart > max) {
      if (prevMatch !== foldStart) foldEnd = prevMatch;
      else foldEnd = index;

      if (result) result += '\n';
      folded = line.slice(foldStart, foldEnd);
      result += folded;
      foldStart = foldEnd + 1;
    }
    prevMatch = index + 1;
    match = foldRe.exec(line);
  }

  if (result) result += '\n';

  // if we end up with one last word at the end, then the last bit might
  // be slightly bigger than we wanted, because we exited out of the loop.
  if (foldStart !== prevMatch && line.length - foldStart > max) {
    result += line.slice(foldStart, prevMatch) + '\n' +
              line.slice(prevMatch + 1);
  } else {
    result += line.slice(foldStart);
  }

  return result;
}

// Returns true if character can be found in a simple scalar
function simpleChar(character) {
  return CHAR_TAB                  !== character &&
         CHAR_LINE_FEED            !== character &&
         CHAR_CARRIAGE_RETURN      !== character &&
         CHAR_COMMA                !== character &&
         CHAR_LEFT_SQUARE_BRACKET  !== character &&
         CHAR_RIGHT_SQUARE_BRACKET !== character &&
         CHAR_LEFT_CURLY_BRACKET   !== character &&
         CHAR_RIGHT_CURLY_BRACKET  !== character &&
         CHAR_SHARP                !== character &&
         CHAR_AMPERSAND            !== character &&
         CHAR_ASTERISK             !== character &&
         CHAR_EXCLAMATION          !== character &&
         CHAR_VERTICAL_LINE        !== character &&
         CHAR_GREATER_THAN         !== character &&
         CHAR_SINGLE_QUOTE         !== character &&
         CHAR_DOUBLE_QUOTE         !== character &&
         CHAR_PERCENT              !== character &&
         CHAR_COLON                !== character &&
         !ESCAPE_SEQUENCES[character]            &&
         !needsHexEscape(character);
}

// Returns true if the character code needs to be escaped.
function needsHexEscape(character) {
  return !((0x00020 <= character && character <= 0x00007E) ||
           (character === 0x00085)                         ||
           (0x000A0 <= character && character <= 0x00D7FF) ||
           (0x0E000 <= character && character <= 0x00FFFD) ||
           (0x10000 <= character && character <= 0x10FFFF));
}

function writeFlowSequence(state, level, object) {
  var _result = '',
      _tag    = state.tag,
      index,
      length;

  for (index = 0, length = object.length; index < length; index += 1) {
    // Write only valid elements.
    if (writeNode(state, level, object[index], false, false)) {
      if (index !== 0) _result += ', ';
      _result += state.dump;
    }
  }

  state.tag = _tag;
  state.dump = '[' + _result + ']';
}

function writeBlockSequence(state, level, object, compact) {
  var _result = '',
      _tag    = state.tag,
      index,
      length;

  for (index = 0, length = object.length; index < length; index += 1) {
    // Write only valid elements.
    if (writeNode(state, level + 1, object[index], true, true)) {
      if (!compact || index !== 0) {
        _result += generateNextLine(state, level);
      }
      _result += '- ' + state.dump;
    }
  }

  state.tag = _tag;
  state.dump = _result || '[]'; // Empty sequence if no valid values.
}

function writeFlowMapping(state, level, object) {
  var _result       = '',
      _tag          = state.tag,
      objectKeyList = Object.keys(object),
      index,
      length,
      objectKey,
      objectValue,
      pairBuffer;

  for (index = 0, length = objectKeyList.length; index < length; index += 1) {
    pairBuffer = '';

    if (index !== 0) pairBuffer += ', ';

    objectKey = objectKeyList[index];
    objectValue = object[objectKey];

    if (!writeNode(state, level, objectKey, false, false)) {
      continue; // Skip this pair because of invalid key;
    }

    if (state.dump.length > 1024) pairBuffer += '? ';

    pairBuffer += state.dump + ': ';

    if (!writeNode(state, level, objectValue, false, false)) {
      continue; // Skip this pair because of invalid value.
    }

    pairBuffer += state.dump;

    // Both key and value are valid.
    _result += pairBuffer;
  }

  state.tag = _tag;
  state.dump = '{' + _result + '}';
}

function writeBlockMapping(state, level, object, compact) {
  var _result       = '',
      _tag          = state.tag,
      objectKeyList = Object.keys(object),
      index,
      length,
      objectKey,
      objectValue,
      explicitPair,
      pairBuffer;

  // Allow sorting keys so that the output file is deterministic
  if (state.sortKeys === true) {
    // Default sorting
    objectKeyList.sort();
  } else if (typeof state.sortKeys === 'function') {
    // Custom sort function
    objectKeyList.sort(state.sortKeys);
  } else if (state.sortKeys) {
    // Something is wrong
    throw new YAMLException('sortKeys must be a boolean or a function');
  }

  for (index = 0, length = objectKeyList.length; index < length; index += 1) {
    pairBuffer = '';

    if (!compact || index !== 0) {
      pairBuffer += generateNextLine(state, level);
    }

    objectKey = objectKeyList[index];
    objectValue = object[objectKey];

    if (!writeNode(state, level + 1, objectKey, true, true, true)) {
      continue; // Skip this pair because of invalid key.
    }

    explicitPair = (state.tag !== null && state.tag !== '?') ||
                   (state.dump && state.dump.length > 1024);

    if (explicitPair) {
      if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
        pairBuffer += '?';
      } else {
        pairBuffer += '? ';
      }
    }

    pairBuffer += state.dump;

    if (explicitPair) {
      pairBuffer += generateNextLine(state, level);
    }

    if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
      continue; // Skip this pair because of invalid value.
    }

    if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
      pairBuffer += ':';
    } else {
      pairBuffer += ': ';
    }

    pairBuffer += state.dump;

    // Both key and value are valid.
    _result += pairBuffer;
  }

  state.tag = _tag;
  state.dump = _result || '{}'; // Empty mapping if no valid pairs.
}

function detectType(state, object, explicit) {
  var _result, typeList, index, length, type, style;

  typeList = explicit ? state.explicitTypes : state.implicitTypes;

  for (index = 0, length = typeList.length; index < length; index += 1) {
    type = typeList[index];

    if ((type.instanceOf  || type.predicate) &&
        (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&
        (!type.predicate  || type.predicate(object))) {

      state.tag = explicit ? type.tag : '?';

      if (type.represent) {
        style = state.styleMap[type.tag] || type.defaultStyle;

        if (_toString.call(type.represent) === '[object Function]') {
          _result = type.represent(object, style);
        } else if (_hasOwnProperty.call(type.represent, style)) {
          _result = type.represent[style](object, style);
        } else {
          throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style');
        }

        state.dump = _result;
      }

      return true;
    }
  }

  return false;
}

// Serializes `object` and writes it to global `result`.
// Returns true on success, or false on invalid object.
//
function writeNode(state, level, object, block, compact, iskey) {
  state.tag = null;
  state.dump = object;

  if (!detectType(state, object, false)) {
    detectType(state, object, true);
  }

  var type = _toString.call(state.dump);

  if (block) {
    block = (state.flowLevel < 0 || state.flowLevel > level);
  }

  var objectOrArray = type === '[object Object]' || type === '[object Array]',
      duplicateIndex,
      duplicate;

  if (objectOrArray) {
    duplicateIndex = state.duplicates.indexOf(object);
    duplicate = duplicateIndex !== -1;
  }

  if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {
    compact = false;
  }

  if (duplicate && state.usedDuplicates[duplicateIndex]) {
    state.dump = '*ref_' + duplicateIndex;
  } else {
    if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {
      state.usedDuplicates[duplicateIndex] = true;
    }
    if (type === '[object Object]') {
      if (block && (Object.keys(state.dump).length !== 0)) {
        writeBlockMapping(state, level, state.dump, compact);
        if (duplicate) {
          state.dump = '&ref_' + duplicateIndex + state.dump;
        }
      } else {
        writeFlowMapping(state, level, state.dump);
        if (duplicate) {
          state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
        }
      }
    } else if (type === '[object Array]') {
      if (block && (state.dump.length !== 0)) {
        writeBlockSequence(state, level, state.dump, compact);
        if (duplicate) {
          state.dump = '&ref_' + duplicateIndex + state.dump;
        }
      } else {
        writeFlowSequence(state, level, state.dump);
        if (duplicate) {
          state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
        }
      }
    } else if (type === '[object String]') {
      if (state.tag !== '?') {
        writeScalar(state, state.dump, level, iskey);
      }
    } else {
      if (state.skipInvalid) return false;
      throw new YAMLException('unacceptable kind of an object to dump ' + type);
    }

    if (state.tag !== null && state.tag !== '?') {
      state.dump = '!<' + state.tag + '> ' + state.dump;
    }
  }

  return true;
}

function getDuplicateReferences(object, state) {
  var objects = [],
      duplicatesIndexes = [],
      index,
      length;

  inspectNode(object, objects, duplicatesIndexes);

  for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {
    state.duplicates.push(objects[duplicatesIndexes[index]]);
  }
  state.usedDuplicates = new Array(length);
}

function inspectNode(object, objects, duplicatesIndexes) {
  var objectKeyList,
      index,
      length;

  if (object !== null && typeof object === 'object') {
    index = objects.indexOf(object);
    if (index !== -1) {
      if (duplicatesIndexes.indexOf(index) === -1) {
        duplicatesIndexes.push(index);
      }
    } else {
      objects.push(object);

      if (Array.isArray(object)) {
        for (index = 0, length = object.length; index < length; index += 1) {
          inspectNode(object[index], objects, duplicatesIndexes);
        }
      } else {
        objectKeyList = Object.keys(object);

        for (index = 0, length = objectKeyList.length; index < length; index += 1) {
          inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
        }
      }
    }
  }
}

function dump(input, options) {
  options = options || {};

  var state = new State(options);

  if (!state.noRefs) getDuplicateReferences(input, state);

  if (writeNode(state, 0, input, true, true)) return state.dump + '\n';

  return '';
}

function safeDump(input, options) {
  return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
}

module.exports.dump     = dump;
module.exports.safeDump = safeDump;
