/* @flow */
import Immutable, {OrderedSet} from 'immutable';

import type {CharacterMetadata} from 'draft-js';
import type {List} from 'immutable';

type EntityKey = ?string;
type Style = OrderedSet<string>;
type StylePiece = [string, Style];
type EntityPiece = [EntityKey, Array<StylePiece>];
export type CharacterMetaList = List<CharacterMetadata>;

export const EMPTY_SET = OrderedSet();

export default function getEntityRanges(
  text: string,
  charMetaList: CharacterMetaList,
): Array<EntityPiece> {
  // TODO: use EMPTY_SET here
  let charEntity = null;
  let prevCharEntity = null;
  let pieces = [];
  let pieceStart = 0;
  for (let i = 0, len = text.length; i < len; i++) {
    prevCharEntity = charEntity;
    let meta = charMetaList.get(i);
    charEntity = meta ? meta.getEntity() : null;
    if (i > 0 && charEntity !== prevCharEntity) {
      pieces.push([
        prevCharEntity,
        getStylePieces(
          text.slice(pieceStart, i),
          charMetaList.slice(pieceStart, i)
        ),
      ]);
      pieceStart = i;
    }
  }
  pieces.push([
    charEntity,
    getStylePieces(
      text.slice(pieceStart),
      charMetaList.slice(pieceStart)
    ),
  ]);
  return pieces;
}

function getStylePieces(
  text: string,
  charMetaList: CharacterMetaList,
): Array<StylePiece> {
  let charStyle = EMPTY_SET;
  let prevCharStyle = EMPTY_SET;
  let pieces = [];
  let pieceStart = 0;
  for (let i = 0, len = text.length; i < len; i++) {
    prevCharStyle = charStyle;
    let meta = charMetaList.get(i);
    charStyle = meta ? meta.getStyle() : EMPTY_SET;
    if (i > 0 && !Immutable.is(charStyle, prevCharStyle)) {
      pieces.push([text.slice(pieceStart, i), prevCharStyle]);
      pieceStart = i;
    }
  }
  pieces.push([text.slice(pieceStart), charStyle]);
  return pieces;
}

@@ -211,20 +211,20 @@
 pe Style
-Piec
+Rang
 e = %5Bstr
@@ -247,20 +247,20 @@
 e Entity
-Piec
+Rang
 e = %5BEnt
@@ -278,20 +278,20 @@
 ay%3CStyle
-Piec
+Rang
 e%3E%5D;%0Aexp
@@ -496,46 +496,16 @@
 tity
-Piece%3E %7B%0A  // TODO: use EMPTY_SET here
+Range%3E %7B
 %0A  l
@@ -553,36 +553,36 @@
 y = null;%0A  let 
-piec
+rang
 es = %5B%5D;%0A  let p
@@ -572,36 +572,36 @@
 ges = %5B%5D;%0A  let 
-piec
+rang
 eStart = 0;%0A  fo
@@ -815,36 +815,36 @@
 Entity) %7B%0A      
-piec
+rang
 es.push(%5B%0A      
@@ -869,36 +869,36 @@
         getStyle
-Piec
+Rang
 es(%0A          te
@@ -898,36 +898,36 @@
      text.slice(
-piec
+rang
 eStart, i),%0A    
@@ -943,36 +943,36 @@
 rMetaList.slice(
-piec
+rang
 eStart, i)%0A     
@@ -985,36 +985,36 @@
       %5D);%0A      
-piec
+rang
 eStart = i;%0A    
@@ -1013,36 +1013,36 @@
  i;%0A    %7D%0A  %7D%0A  
-piec
+rang
 es.push(%5B%0A    ch
@@ -1059,28 +1059,28 @@
     getStyle
-Piec
+Rang
 es(%0A      te
@@ -1080,36 +1080,36 @@
      text.slice(
-piec
+rang
 eStart),%0A      c
@@ -1122,28 +1122,28 @@
 aList.slice(
-piec
+rang
 eStart)%0A    
@@ -1156,28 +1156,28 @@
 );%0A  return 
-piec
+rang
 es;%0A%7D%0A%0Afunct
@@ -1188,20 +1188,20 @@
 getStyle
-Piec
+Rang
 es(%0A  te
@@ -1265,12 +1265,12 @@
 tyle
-Piec
+Rang
 e%3E %7B
@@ -1338,20 +1338,20 @@
 ;%0A  let 
-piec
+rang
 es = %5B%5D;
@@ -1357,20 +1357,20 @@
 ;%0A  let 
-piec
+rang
 eStart =
@@ -1611,20 +1611,20 @@
 %7B%0A      
-piec
+rang
 es.push(
@@ -1631,28 +1631,28 @@
 %5Btext.slice(
-piec
+rang
 eStart, i), 
@@ -1674,20 +1674,20 @@
 ;%0A      
-piec
+rang
 eStart =
@@ -1702,20 +1702,20 @@
 %7D%0A  %7D%0A  
-piec
+rang
 es.push(
@@ -1726,20 +1726,20 @@
 t.slice(
-piec
+rang
 eStart),
@@ -1765,12 +1765,12 @@
 urn 
-piec
+rang
 es;%0A

rename piece -> range for consistency