const updateComment = require('./updateComment.js')

let patterns = []

const buildExplicitCases = (funcdecl, patterndecls) => {
  let patterncases = []
  for (let pattern of patterndecls) {
    let patterncase = {'type': 'SwitchCase', 'consequent': []}
    patterncase.test = pattern.declarations[0].init.params[0]
    let consequent = {'type': 'ReturnStatement'}
    let arg = pattern.declarations[0].init.body
    consequent.argument = arg.type === 'ExpressionStatement' ? arg.expression : arg
    patterncase.consequent.push(consequent)

    patterncases.push(patterncase)
  }
  return patterncases
}

const buildDefaultCase = funcdecl => {
  let defaultcase = {'type': 'SwitchCase', 'test': null, 'consequent': []}
  let consequent = {'type': 'ReturnStatement'}
  let arg = funcdecl.declarations[0].init.body
  consequent.argument = arg.type === 'ExpressionStatement' ? arg.expression : arg
  defaultcase.consequent.push(consequent)
  return defaultcase
}

const formMultiPatternAst = (funcdecl, patterndecls, ast) => {
  let funcdeclbody = {'type': 'BlockStatement', 'body': []}
  let blockstmtbody = {'type': 'SwitchStatement', 'cases': []}
  blockstmtbody.discriminant = funcdecl.declarations[0].init.params[0]
  let cases = buildExplicitCases(funcdecl, patterndecls)
  cases.push(buildDefaultCase(funcdecl))
  blockstmtbody.cases = cases

  funcdeclbody.body.push(blockstmtbody)

  funcdecl.declarations[0].init.body = funcdeclbody
  funcdecl.declarations[0].init.expression = false

  return funcdecl
}

const isArrowFuncDecl = decl => {
  let declarations = decl.declarations

  if (declarations !== undefined && declarations[0].init.type === 'ArrowFunctionExpression') return true
  return false
}

const isFunction = decl => {
  let declarations = decl.declarations
  let funcexp = declarations[0].init
  let params = funcexp.params

  let isFunc = true
  for (let param of params) {
    if (param.type === 'Literal' || param.type === 'ArrayExpression' || param.type === 'ObjectExpression') {
      isFunc = false
      break
    }
  }
  return isFunc
}

const formFunctionAst = (funcdecl, patterndecls) => {
  let patternscount = patterndecls.length
  return patternscount === 0 ? funcdecl : formMultiPatternAst(funcdecl, patterndecls)
}

const processSubTree = decl => {
  if (isArrowFuncDecl(decl)) {
    if (isFunction(decl)) { // funcdeclns
      let funcast = formFunctionAst(decl, patterns)
      patterns = []
      return funcast
    } else { // patternfuncdeclns
      patterns.push(decl)
      return null
    }
  }
  return decl
}

const updateAst = mayBeAst => {
  let ast = mayBeAst
  let newbody = []
  let declarations = ast.body

  declarations.forEach(decl => {
    let subtree = processSubTree(decl)
    if (subtree !== null) newbody.push(subtree)
  })
  newbody = updateComment(newbody, ast)
  ast.body = newbody
  return ast
}

/*  Module Exports estemplate  */
module.exports = updateAst

@@ -1,20 +1,63 @@
+const estemplate = require('./estemplate')%0A
 const updateComment 
@@ -88,16 +88,16 @@
 nt.js')%0A
-
 %0Alet pat
@@ -189,16 +189,35 @@
 es = %5B%5D%0A
+  let flag = false%0A
   for (l
@@ -317,24 +317,24 @@
     
+let 
 pattern
-case.test
+Param
  = p
@@ -371,16 +371,338 @@
 rams%5B0%5D%0A
+    patterncase.test = patternParam%0A    if (patternParam.type === 'ArrayExpression') %7B%0A      patterncase.test = estemplate.literal('0')%0A      patterncase.test.sType = %7B%0A        'type': 'array',%0A        'elemTypes': %7B%7D,%0A        'commonType': 'needsInference',%0A        'isHomogeneous': false%0A      %7D%0A      flag = true%0A    %7D%0A
     let 
@@ -963,24 +963,25 @@
  %7D%0A  return 
+%5B
 patterncases
@@ -980,16 +980,23 @@
 erncases
+, flag%5D
 %0A%7D%0A%0Acons
@@ -1539,133 +1539,346 @@
 %7D%0A  
-blockstmtbody.discriminant = funcdecl.declarations%5B0%5D.init.params%5B0%5D%0A  let cases = buildExplicitCases(funcdecl, patterndecls)
+let %5Bcases, flag%5D = buildExplicitCases(funcdecl, patterndecls)%0A  let testTempl = funcdecl.declarations%5B0%5D.init.params%5B0%5D%0A  blockstmtbody.discriminant = testTempl%0A  if (flag === true) %7B%0A    let lengthTempl = estemplate.identifier('length')%0A    blockstmtbody.discriminant = estemplate.memberExpression(testTempl, lengthTempl).expression%0A  %7D
 %0A  c

Add support for empty array pattern matching in function definitions