/**
 * @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/core/src/facade/lang';
import {beforeEach, describe, expect, it} from '@angular/core/testing/testing_internal';
import {MessageBundle} from '../../../src/i18n/message_bundle';
import {Xtb} from '../../../src/i18n/serializers/xtb';
import {HtmlParser} from '../../../src/ml_parser/html_parser';
import {DEFAULT_INTERPOLATION_CONFIG} from '../../../src/ml_parser/interpolation_config';
import {serializeNodes} from '../../ml_parser/ast_serializer_spec';
export function main(): void {
  describe('XTB serializer', () => {
    let serializer: Xtb;
    let htmlParser: HtmlParser;
    function loadAsText(template: string, xtb: string): {[id: string]: string} {
      let messageBundle = new MessageBundle(htmlParser, [], {});
      messageBundle.updateFromTemplate(template, 'url', DEFAULT_INTERPOLATION_CONFIG);
      const asAst = serializer.load(xtb, 'url', messageBundle);
      let asText: {[id: string]: string} = {};
      Object.keys(asAst).forEach(id => { asText[id] = serializeNodes(asAst[id]).join(''); });
      return asText;
    }
    beforeEach(() => {
      htmlParser = new HtmlParser();
      serializer = new Xtb(htmlParser, DEFAULT_INTERPOLATION_CONFIG);
    });
    describe('load', () => {
      it('should load XTB files with a doctype', () => {
        const HTML = `
bar
`;
        const XTB = `
]>
  rab
`;
        expect(loadAsText(HTML, XTB)).toEqual({'28a86c8a00ae573b2bac698d6609316dc7b4a226': 'rab'});
      });
      it('should load XTB files without placeholders', () => {
        const HTML = `bar
`;
        const XTB = `
  rab
`;
        expect(loadAsText(HTML, XTB)).toEqual({'28a86c8a00ae573b2bac698d6609316dc7b4a226': 'rab'});
      });
      it('should load XTB files with placeholders', () => {
        const HTML = ``;
        const XTB = `
  rab
`;
        expect(loadAsText(HTML, XTB)).toEqual({
          '7de4d8ff1e42b7b31da6204074818236a9a5317f': 'rab
'
        });
      });
      it('should replace ICU placeholders with their translations', () => {
        const HTML = `-{ count, plural, =0 {
bar
}}-
rab
}}*`,
          'fc92b9b781194a02ab773129c8c5a7fc0735efd7': `{ count, plural, =1 {rab
}}`,
        });
      });
      it('should load complex XTB files', () => {
        const HTML = `
foo bar {{ a + b }}
{ count, plural, =0 {
bar
}}
foo
{ count, plural, =0 {{ sex, gender, other {
bar
}} }}
rab
}}`,
          'db3e0a6a5a96481f60aec61d98c3eecddef5ac23': `oof`,
          'e3bf2d706c3da16ce05658e07f62f0519f7c561c':
              `{ count, plural, =1 {{ sex, gender, male {rab
}} }}`,
        });
      });
    });
    describe('errors', () => {
      it('should throw on nested ', () => {
        const XTB =
            '';
        expect(() => {
          loadAsText('', XTB);
        }).toThrowError(/ elements can not be nested/);
      });
      it('should throw when a  has no id attribute', () => {
        const XTB = `
  
`;
        expect(() => {
          loadAsText('', XTB);
        }).toThrowError(/ misses the "id" attribute/);
      });
      it('should throw when a placeholder has no name attribute', () => {
        const HTML = 'give me a message
';
        const XTB = `
  
`;
        expect(() => { loadAsText(HTML, XTB); }).toThrowError(/ misses the "name" attribute/);
      });
      it('should throw when a placeholder is not present in the source message', () => {
        const HTML = `bar
`;
        const XTB = `
  
`;
        expect(() => {
          loadAsText(HTML, XTB);
        }).toThrowError(/The placeholder "UNKNOWN" does not exists in the source message/);
      });
    });
    it('should throw when the translation results in invalid html', () => {
      const HTML = ``;
      const XTB = `
  rab
`;
      expect(() => {
        loadAsText(HTML, XTB);
      }).toThrowError(/xtb parse errors:\nUnexpected closing tag "p"/);
    });
    it('should throw on unknown tags', () => {
      const XTB = ``;
      expect(() => {
        loadAsText('', XTB);
      }).toThrowError(new RegExp(escapeRegExp(`Unexpected tag ("[ERROR ->]")`)));
    });
    it('should throw when trying to save an xtb file',
       () => { expect(() => { serializer.write({}); }).toThrowError(/Unsupported/); });
  });
}