import Importer from 'node-matrix-importer'

export default function assetsToXML (assets, parentId) {
  let assetMap = []
  let xml

  if (assets instanceof Importer) {
    xml = assets

    return processAssets
  } else {
    xml = new Importer({
      sortActions: true
    })

    return processAssets(assets, parentId)
  }

  function processAssets (assets, parentId) {
    processAsset(assets, parentId)

    return xml.toString()
  }

  function processAsset (asset, parentId) {
    const {
      children = [],
      dependant,
      exclusive,
      key,
      type
    } = asset

    const links = Object.keys(asset.link)
    const permissions = Object.keys(asset.permissions)

    const [ link ] = links.filter(linkTypeN)
    const value = asset.link[link]

    const createdAsset = createAsset({
      parentId,
      type,
      link,
      value,
      dependant,
      exclusive
    })
    const { id: assetId } = createdAsset

    assetMap[key] = assetId

    permissions.forEach(setPermissions(asset.permissions))
    createChildren(assetId, children)
    createLinks(createdAsset, asset)
    setAttributes(createdAsset, asset)
    setPaths(createdAsset, asset)

    function setPermissions (permissions) {
      return function setPermission (permission) {
        const { allow, deny } = permissions[permission]

        allowUsers(allow)
        denyUsers(deny)

        function allowUsers (users) {
          permissionsToSet(users, true)
        }

        function denyUsers (users) {
          permissionsToSet(users, false)
        }

        function permissionsToSet (users = [], granted) {
          users.forEach((userId) => {
            xml.setPermission({
              assetId,
              permission,
              granted,
              userId
            })
          })
        }
      }
    }
  }

  function createAsset (opts) {
    if (typeof opts.value === 'boolean') {
      delete opts.value
    }
    return xml.createAsset(opts)
  }

  function createChildren (assetId, children) {
    children.forEach(function processChild (child) {
      processAsset(child, assetId)
    })
  }

  function createLinks ({ id: assetId }, { link }) {
    const links = Object.keys(link)

    links.filter(noticeLink).forEach(function createLink (link) {
      xml.createLink({
        to: assetMap[links[link].key],
        from: assetId,
        link: 'notice',
        value: link
      })
    })
  }

  function setAttributes ({ id: assetId }, { attributes }) {
    Object.keys(attributes).forEach(function setAttribute (attribute) {
      const value = attributes[attribute]
      xml.setAttribute({
        assetId,
        attribute,
        value
      })
    })
  }

  function setPaths ({ id: assetId }, { paths }) {
    paths.forEach(function setPath (path) {
      xml.addPath({
        assetId,
        path
      })
    })
  }
}

function linkTypeN (link) {
  return /^type_[1-3]$/.test(link)
}

function noticeLink (link) {
  return !linkTypeN(link)
}

@@ -627,63 +627,8 @@
 ink)
-%0A    const permissions = Object.keys(asset.permissions)
 %0A%0A  
@@ -913,67 +913,8 @@
 Id%0A%0A
-    permissions.forEach(setPermissions(asset.permissions))%0A
     
@@ -1061,22 +1061,12 @@
 et)%0A
-%0A
     
-function 
 setP
@@ -1079,634 +1079,29 @@
 ions
- (permissions) %7B%0A      return function setPermission (permission) %7B%0A        const %7B allow, deny %7D = permissions%5Bpermission%5D%0A%0A        allowUsers(allow)%0A        denyUsers(deny)%0A%0A        function allowUsers (users) %7B%0A          permissionsToSet(users, true)%0A        %7D%0A%0A        function denyUsers (users) %7B%0A          permissionsToSet(users, false)%0A        %7D%0A%0A        function permissionsToSet (users = %5B%5D, granted) %7B%0A          users.forEach((userId) =%3E %7B%0A            xml.setPermission(%7B%0A              assetId,%0A              permission,%0A              granted,%0A              userId%0A            %7D)%0A          %7D)%0A        %7D%0A      %7D%0A    %7D
+(createdAsset, asset)
 %0A  %7D
@@ -2094,32 +2094,32 @@
        assetId,%0A
-
         path%0A   
@@ -2134,16 +2134,658 @@
   %7D)%0A  %7D
+%0A%0A  function setPermissions (%7B id: assetId %7D, %7B permissions %7D) %7B%0A    Object.keys(permissions).forEach(function processPermission (permission) %7B%0A      const %7B%0A        allow: allowed = %5B%5D,%0A        deny: denied = %5B%5D%0A      %7D = permissions%5Bpermission%5D%0A%0A      setAssetPermissionForUsers(assetId, permission, true, allowed)%0A      setAssetPermissionForUsers(assetId, permission, false, denied)%0A    %7D)%0A  %7D%0A%0A  function setAssetPermissionForUsers (assetId, permission, granted, users) %7B%0A    users.forEach(function setPermission (userId) %7B%0A      xml.setPermission(%7B%0A        assetId,%0A        permission,%0A        granted,%0A        userId%0A      %7D)%0A    %7D)%0A  %7D
 %0A%7D%0A%0Afunc

Refactor setPermissions function