/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
import {AST} from '../../../src/expression_parser/ast';
import {Lexer} from '../../../src/expression_parser/lexer';
import {Parser} from '../../../src/expression_parser/parser';
import * as i18n from '../../../src/i18n/i18n_ast';
import * as o from '../../../src/output/output_ast';
import * as t from '../../../src/render3/r3_ast';
import {I18nContext} from '../../../src/render3/view/i18n/context';
import {getSerializedI18nContent} from '../../../src/render3/view/i18n/serializer';
import {I18nMeta, formatI18nPlaceholderName, parseI18nMeta} from '../../../src/render3/view/i18n/util';
import {parseR3 as parse} from './util';
const expressionParser = new Parser(new Lexer());
const i18nOf = (element: t.Node & {i18n?: i18n.AST}) => element.i18n !;
describe('I18nContext', () => {
  it('should support i18n content collection', () => {
    const ref = o.variable('ref');
    const ast = new i18n.Message([], {}, {}, '', '', '');
    const ctx = new I18nContext(5, ref, 0, null, ast);
    // basic checks
    expect(ctx.isRoot).toBe(true);
    expect(ctx.isResolved).toBe(true);
    expect(ctx.id).toBe(0);
    expect(ctx.ref).toBe(ref);
    expect(ctx.index).toBe(5);
    expect(ctx.templateIndex).toBe(null);
    const tree = parse('
');
    const [boundText, element, template] = (tree.nodes[0] as t.Element).children;
    // data collection checks
    expect(ctx.placeholders.size).toBe(0);
    ctx.appendBoundText(i18nOf(boundText));       // interpolation
    ctx.appendElement(i18nOf(element), 1);        // open tag
    ctx.appendElement(i18nOf(element), 1, true);  // close tag
    ctx.appendTemplate(i18nOf(template), 2);      // open + close tags
    expect(ctx.placeholders.size).toBe(5);
    // binding collection checks
    expect(ctx.bindings.size).toBe(0);
    ctx.appendBinding(expressionParser.parseInterpolation('{{ valueA }}', '') as AST);
    ctx.appendBinding(expressionParser.parseInterpolation('{{ valueB }}', '') as AST);
    expect(ctx.bindings.size).toBe(2);
  });
  it('should support nested contexts', () => {
    const template = `
      
        A {{ valueA }}
        
A
        
          B {{ valueB }}
          B
          C {{ valueC }}
        
      ${input}
`);
    const root = tree.nodes[0] as t.Element;
    return getSerializedI18nContent(root.i18n as i18n.Message);
  };
  it('should produce output for i18n content', () => {
    const cases = [
      // plain text
      ['Some text', 'Some text'],
      // text with interpolation
      [
        'Some text {{ valueA }} and {{ valueB + valueC }}',
        'Some text {$interpolation} and {$interpolation_1}'
      ],
      // content with HTML tags
      [
        'A BC
 D',
        'A {$startTagSpan}B{$startTagDiv}C{$closeTagDiv}{$closeTagSpan} D'
      ],
      // simple ICU
      ['{age, plural, 10 {ten} other {other}}', '{VAR_PLURAL, plural, 10 {ten} other {other}}'],
      // nested ICUs
      [
        '{age, plural, 10 {ten {size, select, 1 {one} 2 {two} other {2+}}} other {other}}',
        '{VAR_PLURAL, plural, 10 {ten {VAR_SELECT, select, 1 {one} 2 {two} other {2+}}} other {other}}'
      ],
      // ICU with nested HTML
      [
        '{age, plural, 10 {ten} other {other
}}',
        '{VAR_PLURAL, plural, 10 {{$startBoldText}ten{$closeBoldText}} other {{$startTagDiv}other{$closeTagDiv}}}'
      ]
    ];
    cases.forEach(([input, output]) => { expect(serialize(input)).toEqual(output); });
  });
});