﻿module wizzi-mtree@${wzCtx.version}.loader.includer
    kind es6
    
	var util = require('util')
    var path = require('path')
	var async = require('async')
    var errors = require('../errors')
	var verify = require('@wizzi/utils').verify
    var utilnode = require('../utils/node')

	#
		# Ittf commands
		#   $include
		#   $json
        #   $fragment
    
	var includer
        set module.exports =
            function 
                { primaryMTreeBrick
                { mTreeBrickProvider
                callback
                
				var includes
                    [ 
                
				var jsons
                    [ 
                
				var fragments
                    [ 

				foreach node in primaryMTreeBrick.nodes
                    _ searchCommands
                        @ node
                        @ includes
                        @ jsons
                        @ fragments

                # loog 'wizzi-mtree.includer.fragments before', primaryMTreeBrick.documentFragments
                set primaryMTreeBrick.documentFragments = fragments
                # loog 'wizzi-mtree.includer.fragments after', primaryMTreeBrick.documentFragments
                
				_ async.mapSeries
					@ includes
					function
						param item
						param callback
						var v = item.value.trim()
						var includerUri = item.model.uri
						var includerBaseDir = path.dirname(includerUri)
						_ mTreeBrickProvider.get
							{ 
								@ from 'store'
								@ basedir includerBaseDir
								@ relpath v
								@ include true
								@ includerBrickKey item.model.brickKey
                                @ includerMTreeBrick primaryMTreeBrick
							f_cb_no_err( includedWipNodifiedMTree )
								if err
									if err.__is_wizzi_error
										set err.mtree
											{
												@ includerUri includerUri
												@ includedRelPath v
										return 
											_ callback
												@ err
									return
										_ callback
                                            _ local_error
                                                @ 'IttfIncludeError'
                                                @ 'includer'
                                                @ 'Fragment to include not found'
                                                @ item
                                                @ err
                                                {
													{ mtree
														@ includerUri includerUri
														@ includedRelPath v
								_ mTreeBrickProvider.enterFragmentCall
									@ includerUri
									@ includedWipNodifiedMTree.uri
								if mTreeBrickProvider.checkForRecursion()
									return
										_ callback
											_ local_error
												@ 'IttfIncludeError'
												@ 'default'
												@ 'Recursive mixin or include: ' + v
												@ node
								_ includer
									@ includedWipNodifiedMTree
									@ mTreeBrickProvider
									f_cb( includeResult )
										_ mTreeBrickProvider.exitFragmentCall()
										# _ mTreeBrickProvider.callChain.pop()
                                        if !item.parent
                                            return
                                                _ callback
                                                    _ local_error
                                                        @ 'IttfIncludeError'
                                                        @ 'includer'
                                                        @ 'A $include command cannot be a root node.'
                                                        @ item
                                                        @ err
                                                        {
															{ mtree
																@ includerUri includerUri
																@ includedRelPath v
										_ utilnode.replace
											@ item
											@ includeResult.nodes
										return
											_ callback
												@ null
					f_cb( results )
						foreach item in jsons
							var json
								_ JSON.parse
									@ item.value
							if verify.isArray(json)
								var normalized
									[ 
								foreach jsonitem in json
									_ normalized.push
										_ normalizeNode
											@ jsonitem
											@ item.parent
											@ item.model
											@ item.row
											@ item.col
											@ item.sourceKey
								_ utilnode.replace(item, normalized)
							else 
								var normalized
									_ normalizeNode
										@ json
										@ item.parent
										@ item.model
										@ item.row
										@ item.col
										@ item.sourceKey
								_ utilnode.replace
									@ item
									[ 
										@ normalized
                        _ callback(null, primaryMTreeBrick)
    
	function searchCommands
        param item
        param includes
        param jsons
        param fragments
        if item.name === '$include'
            _ includes.push(item)
        elif item.name === '$json'
            _ jsons.push(item)
        elif item.name === '$fragment'
            _ fragments.push(item)
        foreach child in item.children
            _ searchCommands
                @ child
                @ includes
                @ jsons
                @ fragments
    
	function normalizeNode
        param node
        param parent
        param model
        param r
        param c
        param u
        set node.parent = parent
        set node.model = model
        set node.row = r
        set node.col = c
        set node.souceKey = u
		if node.children
			foreach item in node.children
				_ normalizeNode(item, node, model, r, c, u)
        else
            set node.children = []

	local_error( wizzi-mtree@${wzCtx.version}.loader.includer )