'use strict'

const xtend = require('xtend')
const unified = require('unified')
const parse = require('remark-parse')
const PropTypes = require('prop-types')
const defaultRenderers = require('./renderers')
const getDefinitions = require('./get-definitions')
const astToReact = require('./ast-to-react')
const wrapTableRows = require('./wrap-table-rows')
const disallowNode = require('./plugins/disallow-node')
const naiveHtml = require('./plugins/naive-html')

const allTypes = Object.keys(defaultRenderers)

const ReactMarkdown = function ReactMarkdown(props) {
  const src = props.source || props.children || ''

  if (props.allowedTypes && props.disallowedTypes) {
    throw new Error('Only one of `allowedTypes` and `disallowedTypes` should be defined')
  }

  const renderers = xtend(defaultRenderers, props.renderers)

  let disallowedTypes = props.disallowedTypes || []
  if (props.allowedTypes) {
    disallowedTypes = allTypes.filter(
      type => type !== 'root' && props.allowedTypes.indexOf(type) === -1
    )
  }

  const plugins = [wrapTableRows]

  const removalMethod = props.unwrapDisallowed ? 'unwrap' : 'remove'
  if (disallowedTypes.length > 0) {
    plugins.push(disallowNode.ofType(disallowedTypes, removalMethod))
  }

  if (props.allowNode) {
    plugins.push(disallowNode.ifNotMatch(props.allowNode, removalMethod))
  }

  const renderHtml = !props.escapeHtml && !props.skipHtml
  if (renderHtml) {
    plugins.push(naiveHtml)
  }

  const rawAst = unified()
    .use(parse)
    .parse(src)

  const ast = plugins.reduce((node, plugin) => plugin(node), rawAst)
  const renderProps = xtend(props, {
    renderers: renderers,
    definitions: getDefinitions(ast)
  })

  return astToReact(ast, renderProps)
}

ReactMarkdown.defaultProps = {
  renderers: {},
  escapeHtml: true,
  skipHtml: false
}

ReactMarkdown.propTypes = {
  className: PropTypes.string,
  source: PropTypes.string,
  children: PropTypes.string,
  sourcePos: PropTypes.bool,
  escapeHtml: PropTypes.bool,
  skipHtml: PropTypes.bool,
  softBreak: PropTypes.string,
  allowNode: PropTypes.func,
  allowedTypes: PropTypes.arrayOf(PropTypes.oneOf(allTypes)),
  disallowedTypes: PropTypes.arrayOf(PropTypes.oneOf(allTypes)),
  transformLinkUri: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
  transformImageUri: PropTypes.func,
  unwrapDisallowed: PropTypes.bool,
  renderers: PropTypes.object
}

module.exports = ReactMarkdown

@@ -818,16 +818,404 @@
 erers)%0A%0A
+  const rawAst = unified()%0A    .use(parse)%0A    .parse(src)%0A%0A  const plugins = determinePlugins(props)%0A  const ast = plugins.reduce((node, plugin) =%3E plugin(node), rawAst)%0A  const renderProps = xtend(props, %7B%0A    renderers: renderers,%0A    definitions: getDefinitions(ast)%0A  %7D)%0A%0A  return astToReact(ast, renderProps)%0A%7D%0A%0Afunction determinePlugins(props) %7B%0A  const plugins = %5BwrapTableRows%5D%0A%0A
   let di
@@ -1255,14 +1255,8 @@
 ypes
- %7C%7C %5B%5D
 %0A  i
@@ -1407,43 +1407,8 @@
  %7D%0A%0A
-  const plugins = %5BwrapTableRows%5D%0A%0A
   co
@@ -1493,16 +1493,35 @@
 wedTypes
+ && disallowedTypes
 .length 
@@ -1823,278 +1823,22 @@
 %0A%0A  
-const rawAst = unified()%0A    .use(parse)%0A    .parse(src)%0A%0A  const ast = plugins.reduce((node, plugin) =%3E plugin(node), rawAst)%0A  const renderProps = xtend(props, %7B%0A    renderers: renderers,%0A    definitions: getDefinitions(ast)%0A  %7D)%0A%0A  return astToReact(ast, renderProps)
+return plugins
 %0A%7D%0A%0A

Move plugin resolving to separate method