//  iterate array pointer in both arrays to first matching element
//  savedArr: remove and copy all elements (e0) preceding match 
//  processedArr: insert (e0) before pointer
//  repeat
// 
//  if savedArr has elements remaining after loop complete, append to processedArr

const ANSIRegexp = [
  '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
  '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'
].join('|');
const ANSICloseRegexp = new RegExp(`\\u001b\\[0m`)

let processedArr = ["r", "e", "\n", "d"]
// let savedArr = [
// "\033[34m", "r", "\033[0m",
// "\033[34m", "e", "\033[0m", 
// "\033[34m", "d", "\033[0m",
// ]
 
 let text = "\033[34mr\033[0m\033[34me\033[0m\033[34md\033[0m"
console.log(text.length)

let escapedRegex = new RegExp(ANSIRegexp, "g")


// get string positions for matches
let matches = []
while((result = escapedRegex.exec(text)) !== null) {
  matches.push({
    start: result.index,
    end: result.index + result[0].length,
    match: result[0]
  })
}

// add start and end positions for non matches
matches = matches.reduce((prev, curr) => {
  // check if space exists between this and last match
  // get end of previous match
  let prevEnd = prev[prev.length -1]

  if (prevEnd.end < curr.start) {
    prev.push({ start: prevEnd.end, end: curr.start }, curr) 
  }
  else {
    prev.push(curr)
  }
  return prev
},[{start:0, end:0}])
  .splice(1) // removes starting accumulator object

// get regex pattern for each split point
let splitStr = matches.map( value => `(.{${value.end - value.start}})` )
  .join('')

// now we have an array of all ansi escaped and non-ansi escaped strings
let savedArr = new RegExp(`^${splitStr}`).exec(text).splice(1)

let restoredANSI = processedArr.map((char) => {
  if (char === '\n') return char

  let splicePoint = savedArr.findIndex(element => element === char) + 1
  let result = savedArr.splice(0, splicePoint)

  // add all consecutive closing tags 
  while (ANSICloseRegexp.test(savedArr[0])){
    result.push(savedArr.shift())
  }

  return result.join("")
}).concat(savedArr)

console.log(restoredANSI)
console.log(restoredANSI.join(""))

// // return immediately if is a closing tag, so no linebreaks in front
// if (ANSICloseRegexp.test(char)) return char
