import { Assert, UnitTest } from '@ephox/bedrock-client';
import { Gene, TestUniverse, TextGene } from '@ephox/boss';
import { Arr } from '@ephox/katamari';

import * as Family from 'ephox/phoenix/api/general/Family';
import * as Finder from 'ephox/phoenix/test/Finder';

UnitTest.test('RangeTest', () => {
  const doc = TestUniverse(
    Gene('root', 'root', [
      Gene('a', 'div', [
        Gene('aa', 'div', [
          TextGene('aaa', 'once upon a time'),
          Gene('aab', 'div', [
            Gene('aaba', 'div', [
              Gene('aabaa', 'img', []),
              TextGene('aabab', ' there was a dragon')
            ])
          ])
        ]),
        Gene('ab', 'div', [
          TextGene('aba', ' called '),
          TextGene('abb', ' not-dragon, '),
          Gene('abc', 'div', [
            Gene('abca', 'br', []),
            TextGene('abcb', 'and that dragon'),
            TextGene('abcc', 'stayed in a far away land'),
            Gene('abcd', 'div', [
              TextGene('abcda', 'free of contaminants')
            ])
          ])
        ]),
        Gene('ac', 'div', [
          TextGene('aca', ' --- OCD he was, ')
        ])
      ]),
      TextGene('b', 'yes')
    ])
  );

  const check = (expected: string[], startId: string, finishId: string, delta1: number, delta2: number) => {
    const start = Finder.get(doc, startId);
    const finish = Finder.get(doc, finishId);
    const actual = Family.range(doc, start, delta1, finish, delta2);
    Assert.eq('', expected, Arr.map(actual, (x) => {
      return x.id;
    }));
  };

  check([ 'a' ], 'a', 'a', 0, 0); // This doesn't check that it is a text node. Is that a problem?
  check([ 'aaa', 'aabab', 'aba', 'abb' ], 'aaa', 'abca', 0, 0);
  check([ 'aaa' ], 'aaa', 'aaa', 1, 1);
  check([ 'aabab', 'aba', 'abb', 'abcb', 'abcc', 'abcda' ], 'aabab', 'aca', 0, 0);
  check([ 'aabab', 'aba', 'abb', 'abcb', 'abcc', 'abcda', 'aca' ], 'aabab', 'aca', 0, 1);
  check([ 'aba', 'abb', 'abcb', 'abcc', 'abcda', 'aca' ], 'aabab', 'aca', 1, 1);

  check([ 'abcb', 'abcc' ], 'abc', 'abcda', 0, 0);
  check([ 'aaa', 'aabab', 'aba', 'abb', 'abcb', 'abcc', 'abcda' ], 'aa', 'ac', 0, 1);
});
