/**
 * @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 {escapeRegExp} from '@angular/compiler/src/util';
import {serializeNodes} from '../../../src/i18n/digest';
import * as i18n from '../../../src/i18n/i18n_ast';
import {Xtb} from '../../../src/i18n/serializers/xtb';
export function main(): void {
  describe('XTB serializer', () => {
    const serializer = new Xtb();
    function loadAsMap(xtb: string): {[id: string]: string} {
      const {i18nNodesByMsgId} = serializer.load(xtb, 'url');
      const msgMap: {[id: string]: string} = {};
      Object.keys(i18nNodesByMsgId).forEach(id => {
        msgMap[id] = serializeNodes(i18nNodesByMsgId[id]).join('');
      });
      return msgMap;
    }
    describe('load', () => {
      it('should load XTB files with a doctype', () => {
        const XTB = `
]>
  rab
`;
        expect(loadAsMap(XTB)).toEqual({'8841459487341224498': 'rab'});
      });
      it('should load XTB files without placeholders', () => {
        const XTB = `
  rab
`;
        expect(loadAsMap(XTB)).toEqual({'8841459487341224498': 'rab'});
      });
      it('should return the target locale', () => {
        const XTB = `
  rab
`;
        expect(serializer.load(XTB, 'url').locale).toEqual('fr');
      });
      it('should load XTB files with placeholders', () => {
        const XTB = `
  rab
`;
        expect(loadAsMap(XTB)).toEqual({
          '8877975308926375834': 'rab'
        });
      });
      it('should replace ICU placeholders with their translations', () => {
        const XTB = `
  **
  {VAR_PLURAL, plural, =1 {rab}}
`;
        expect(loadAsMap(XTB)).toEqual({
          '7717087045075616176': `**`,
          '5115002811911870583':
              `{VAR_PLURAL, plural, =1 {[, rab, ]}}`,
        });
      });
      it('should load complex XTB files', () => {
        const XTB = `
  rab oof
  {VAR_PLURAL, plural, =1 {rab}}
  oof
  {VAR_PLURAL, plural, =1 {{VAR_GENDER, gender, male {rab}} }}
`;
        expect(loadAsMap(XTB)).toEqual({
          '8281795707202401639':
              `rab oof`,
          '5115002811911870583':
              `{VAR_PLURAL, plural, =1 {[, rab, ]}}`,
          '130772889486467622': `oof`,
          '4739316421648347533':
              `{VAR_PLURAL, plural, =1 {[{VAR_GENDER, gender, male {[, rab, ]}},  ]}}`,
        });
      });
    });
    describe('errors', () => {
      it('should be able to parse non-angular xtb files without error', () => {
        const XTB = `
  is great
  is less {count, plural, =0 {{GREAT}}}
`;
        // Invalid messages should not cause the parser to throw
        let i18nNodesByMsgId: {[id: string]: i18n.Node[]} = undefined !;
        expect(() => {
          i18nNodesByMsgId = serializer.load(XTB, 'url').i18nNodesByMsgId;
        }).not.toThrow();
        expect(Object.keys(i18nNodesByMsgId).length).toEqual(2);
        expect(serializeNodes(i18nNodesByMsgId['angular']).join('')).toEqual('is great');
        // Messages that contain unsupported feature should throw on access
        expect(() => {
          const read = i18nNodesByMsgId['non angular'];
        }).toThrowError(/xtb parse errors/);
      });
      it('should throw on nested ', () => {
        const XTB =
            '';
        expect(() => {
          loadAsMap(XTB);
        }).toThrowError(/ elements can not be nested/);
      });
      it('should throw when a  has no id attribute', () => {
        const XTB = `
  
`;
        expect(() => { loadAsMap(XTB); }).toThrowError(/ misses the "id" attribute/);
      });
      it('should throw when a placeholder has no name attribute', () => {
        const XTB = `
  
`;
        expect(() => { loadAsMap(XTB); }).toThrowError(/ misses the "name" attribute/);
      });
      it('should throw on unknown xtb tags', () => {
        const XTB = ``;
        expect(() => {
          loadAsMap(XTB);
        }).toThrowError(new RegExp(escapeRegExp(`Unexpected tag ("[ERROR ->]")`)));
      });
      it('should throw on unknown message tags', () => {
        const XTB = `
  msg should contain only ph tags
`;
        expect(() => { loadAsMap(XTB); })
            .toThrowError(
                new RegExp(escapeRegExp(`[ERROR ->]msg should contain only ph tags`)));
      });
      it('should throw on duplicate message id', () => {
        const XTB = `
  msg1
  msg2
`;
        expect(() => {
          loadAsMap(XTB);
        }).toThrowError(/Duplicated translations for msg 1186013544048295927/);
      });
      it('should throw when trying to save an xtb file',
         () => { expect(() => { serializer.write([], null); }).toThrowError(/Unsupported/); });
    });
  });
}