/**
 * @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 {MessageBundle} from '../../../src/i18n/message_bundle';
import {Xliff2} from '../../../src/i18n/serializers/xliff2';
import {HtmlParser} from '../../../src/ml_parser/html_parser';
import {DEFAULT_INTERPOLATION_CONFIG} from '../../../src/ml_parser/interpolation_config';
const HTML = `
not translatable
translatable element with placeholders  {{ interpolation}}
{ count, plural, =0 {test
}}
foo
{{interpolation}} Text 
hello 
{ count, plural, =0 { { sex, select, other {
deeply nested
}} }}
Test: { count, plural, =0 { { sex, select, other {
deeply nested
}} } =other {a lot}}
multi
lines
`;
const WRITE_XLIFF = `
  
    
      
        file.ts:2 
       
      
        translatable attribute 
       
     
    
      
        file.ts:3 
       
      
        translatable element with placeholders   
       
     
    
      
        file.ts:4 
       
      
        {VAR_PLURAL, plural, =0 {test } } 
       
     
    
      
        d 
        m 
        file.ts:5 
       
      
        foo 
       
     
    
      
        nested 
        file.ts:6 
       
      
         
     
    
      
        ph names 
        file.ts:7 
       
      
         
     
    
      
        empty element 
        file.ts:8 
       
      
        hello  
       
     
    
      
        file.ts:9 
       
      
        {VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {deeply nested } } } } 
       
     
    
      
        file.ts:10 
       
      
        Test:  
       
     
    
      
        file.ts:10 
       
      
        {VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {deeply nested } } } =other {a lot} } 
       
     
    
      
        file.ts:11,12 
       
      
        multi
lines 
       
     
   
 
`;
const LOAD_XLIFF = `
  
    
      
        file.ts:2 
       
      
        translatable attribute 
        etubirtta elbatalsnart 
       
     
    
      
        file.ts:3 
       
      
        translatable element with placeholders   
        sredlohecalp htiw  tnemele elbatalsnart 
     
    
      
        file.ts:4 
       
      
        {VAR_PLURAL, plural, =0 {test } } 
        {VAR_PLURAL, plural, =0 {TEST } } 
       
     
    
      
        d 
        m 
        file.ts:5 
       
      
        foo 
        oof 
       
     
    
      
        nested 
        file.ts:6 
       
      
        txeT   
     
    
      
        ph names 
        file.ts:7 
       
      
         
     
    
      
        empty element 
        file.ts:8 
       
      
        hello  
         
     
    
      
        file.ts:9 
       
      
        {VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {deeply nested } } } } 
        {VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {profondément imbriqué } } } } 
       
     
    
      
        file.ts:10 
       
      
        Test:  
        Test:  
       
     
    
      
        file.ts:10 
       
      
        {VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {deeply nested } } } =other {a lot} } 
        {VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {profondément imbriqué } } } =other {beaucoup} } 
       
     
    
      
        file.ts:11,12 
       
      
        multi
lines 
        multi
lignes 
       
     
    
     
      Please check the translation for 'namespace'. On also can use 'espace de nom',but I think most technical manuals use the English term. 
      
     
      You use your own namespace. 
      Vous pouvez utiliser votre propre namespace . 
      
     
    
     
      Please check the translation for 'namespace'. On also can use 'espace de nom',but I think most technical manuals use the English term. 
      
     
      You use your own namespace. 
      Vous pouvez utiliser votre propre namespace  . 
      
     
   
 
`;
(function() {
  const serializer = new Xliff2();
  function toXliff(html: string, locale: string | null = null): string {
    const catalog = new MessageBundle(new HtmlParser, [], {}, locale);
    catalog.updateFromTemplate(html, 'file.ts', DEFAULT_INTERPOLATION_CONFIG);
    return catalog.write(serializer);
  }
  function loadAsMap(xliff: string): {[id: string]: string} {
    const {i18nNodesByMsgId} = serializer.load(xliff, 'url');
    const msgMap: {[id: string]: string} = {};
    Object.keys(i18nNodesByMsgId)
        .forEach(id => msgMap[id] = serializeNodes(i18nNodesByMsgId[id]).join(''));
    return msgMap;
  }
  describe('XLIFF 2.0 serializer', () => {
    describe('write', () => {
      it('should write a valid xliff 2.0 file',
         () => { expect(toXliff(HTML)).toEqual(WRITE_XLIFF); });
      it('should write a valid xliff 2.0 file with a source language',
         () => { expect(toXliff(HTML, 'fr')).toContain('srcLang="fr"'); });
    });
    describe('load', () => {
      it('should load XLIFF files', () => {
        expect(loadAsMap(LOAD_XLIFF)).toEqual({
          '1933478729560469763': 'etubirtta elbatalsnart',
          '7056919470098446707':
              '
  
    
      
         
    
   
 `;
        expect(() => {
          loadAsMap(XLIFF);
        }).toThrowError(/The XLIFF file version 1.2 is not compatible with XLIFF 2.0 serializer/);
      });
      it('should throw when an unit has no translation', () => {
        const XLIFF = `
  
    
      
         
     
   
 `;
        expect(() => {
          loadAsMap(XLIFF);
        }).toThrowError(/Message missingtarget misses a translation/);
      });
      it('should throw when an unit has no id attribute', () => {
        const XLIFF = `
  
    
      
         
     
   
 `;
        expect(() => { loadAsMap(XLIFF); }).toThrowError(/ misses the "id" attribute/);
      });
      it('should throw on duplicate unit id', () => {
        const XLIFF = `
  
    
      
         
     
    
      
         
     
   
 `;
        expect(() => {
          loadAsMap(XLIFF);
        }).toThrowError(/Duplicated translations for msg deadbeef/);
      });
    });
    describe('message errors', () => {
      it('should throw on unknown message tags', () => {
        const XLIFF = `
  
    
      
        msg should contain only ph and pc tags  
     
   
 `;
        expect(() => { loadAsMap(XLIFF); })
            .toThrowError(new RegExp(
                escapeRegExp(`[ERROR ->]msg should contain only ph and pc tags `)));
      });
      it('should throw when a placeholder misses an id attribute', () => {
        const XLIFF = `
  
    
      
         
     
   
 `;
        expect(() => {
          loadAsMap(XLIFF);
        }).toThrowError(new RegExp(escapeRegExp(` misses the "equiv" attribute`)));
      });
    });
  });
})();