var parser = require('js-yaml')
var optionalByteOrderMark = '\\ufeff?'
var platform = typeof process !== 'undefined' ? process.platform : ''
var pattern = '^(' +
  optionalByteOrderMark +
  '(= yaml =|---)' +
  '$([\\s\\S]*?)' +
  '^(?:\\2|\\.\\.\\.)\\s*' +
  '$' +
  (platform === 'win32' ? '\\r?' : '') +
  '(?:\\n)?)'
// NOTE: If this pattern uses the 'g' flag the `regex` variable definition will
// need to be moved down into the functions that use it.
var regex = new RegExp(pattern, 'm')

module.exports = extractor
module.exports.test = test

function extractor (string, options) {
  string = string || ''
  var defaultOptions = { allowUnsafe: false }
  options = options instanceof Object ? { ...defaultOptions, ...options } : defaultOptions
  options.allowUnsafe = Boolean(options.allowUnsafe)
  var lines = string.split(/(\r?\n)/)
  if (lines[0] && /= yaml =|---/.test(lines[0])) {
    return parse(string, options.allowUnsafe)
  } else {
    return {
      attributes: {},
      body: string,
      bodyBegin: 1
    }
  }
}

function computeLocation (match, body) {
  var line = 1
  var pos = body.indexOf('\n')
  var offset = match.index + match[0].length

  while (pos !== -1) {
    if (pos >= offset) {
      return line
    }
    line++
    pos = body.indexOf('\n', pos + 1)
  }

  return line
}

function parse (string, allowUnsafe) {
  var match = regex.exec(string)
  if (!match) {
    return {
      attributes: {},
      body: string,
      bodyBegin: 1
    }
  }

  var loader = allowUnsafe ? parser.load : parser.safeLoad
  var yaml = match[match.length - 1].replace(/^\s+|\s+$/g, '')
  var attributes = loader(yaml) || {}
  var body = string.replace(match[0], '')
  var line = computeLocation(match, string)

  return {
    attributes: attributes,
    body: body,
    bodyBegin: line,
    frontmatter: yaml
  }
}

function test (string) {
  string = string || ''

  return regex.test(string)
}
