/*
 * Copyright (c) 2016 EMC Corporation. All Rights Reserved.
 */
package com.emc.ia.sdk.support.xml;

import static org.junit.Assert.assertEquals;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

import javax.validation.ValidationException;
import javax.xml.XMLConstants;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.w3c.dom.Document;

import com.emc.ia.sdk.support.test.TestCase;


public class WhenWorkingWithXml extends TestCase {

  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @Test
  public void shouldPrettyPrintDocument() {
    String expected = XmlUtil.XML_DECLARATION
        + "<root>\n  <child attr=\"value\"/>\n  <!-- Another child -->\n  <child>\n    <grandChild/>\n  </child>\n"
        + "  <?PI target=\"value\"?>\n  <![CDATA[<>]]>\n</root>\n";
    assertPrettyPrinted(expected);
  }

  private void assertPrettyPrinted(String expected) {
    Document document = XmlUtil.parse(toStream(expected));

    String actual = XmlUtil.toString(document);

    assertEquals("Formatted XML", expected, actual);
  }

  private InputStream toStream(String text) {
    return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
  }

  @Test
  public void shouldSuppressPrintingRootNamespace() {
    String elementName = randomString(5);
    Document document = XmlBuilder.newDocument()
        .namespace(randomString())
        .element(elementName)
        .end()
    .build();

    String actual = XmlUtil.toString(document.getDocumentElement(), false);

    assertEquals("Formatted XML", '<' + elementName + "/>\n", actual);
  }

  @Test
  public void shouldNotThrowExceptionOnValidDocumentWhenValidating() throws IOException {
    String elementName = randomString(8);
    Document document = XmlBuilder.newDocument()
      .element(elementName)
      .build();
    Document schema = someSchema(elementName);

    XmlUtil.validate(toStream(document), toStream(schema), randomString());
  }

  private Document someSchema(String elementName) {
    return XmlBuilder.newDocument()
      .namespace(XMLConstants.W3C_XML_SCHEMA_NS_URI)
      .element("schema")
      .element("element")
      .attribute("name", elementName)
      .attribute("type", "string")
      .build();
  }

  private InputStream toStream(Document document) {
    return toStream(XmlUtil.toString(document));
  }

  @Test
  public void shouldThrowExceptionOnInvalidDocumentWhenValidating() throws IOException {
    Document document = XmlBuilder.newDocument()
      .element(randomString(8))
      .build();
    Document schema = someSchema(randomString(8));

    thrown.expect(ValidationException.class);
    XmlUtil.validate(toStream(document), toStream(schema), randomString());
  }

  @Test
  public void shouldThrowExceptionOnInvalidSchemaWhenValidating() throws IOException {
    Document document = XmlBuilder.newDocument()
      .element(randomString(8))
      .build();

    thrown.expect(ValidationException.class);
    XmlUtil.validate(toStream(document), toStream(document), randomString());
  }

}

@@ -520,17 +520,16 @@
 tCase;%0A%0A
-%0A
 public c
@@ -572,16 +572,90 @@
 Case %7B%0A%0A
+  private static final String NL = System.getProperty(%22line.separator%22);%0A%0A
   @Rule%0A
@@ -814,16 +814,32 @@
 LARATION
+ + %22%3Croot%3E%22 + NL
 %0A       
@@ -846,16 +846,8 @@
  + %22
-%3Croot%3E%5Cn
   %3Cc
@@ -867,18 +867,34 @@
 alue%5C%22/%3E
-%5Cn
+%22 + NL%0A        + %22
   %3C!-- A
@@ -913,40 +913,88 @@
  --%3E
-%5Cn  %3Cchild%3E%5Cn    %3CgrandChild/%3E%5Cn
+%22 + NL%0A        + %22  %3Cchild%3E%22 + NL%0A        + %22    %3CgrandChild/%3E%22 + NL%0A        + %22
   %3C/
@@ -999,19 +999,22 @@
 %3C/child%3E
-%5Cn%22
+%22 + NL
 %0A       
@@ -1046,38 +1046,73 @@
 %5C%22?%3E
-%5Cn  %3C!%5BCDATA%5B%3C%3E%5D%5D%3E%5Cn
+%22 + NL%0A        + %22  %3C!%5BCDATA%5B%3C%3E%5D%5D%3E%22 + NL%0A        + %22
 %3C/root%3E
-%5Cn%22
+%22 + NL
 ;%0A  
@@ -1649,25 +1649,16 @@
 cument()
-%0A        
 .namespa
@@ -1675,25 +1675,16 @@
 tring())
-%0A        
 .element
@@ -1700,28 +1700,14 @@
 ame)
-%0A        
 .end()
-%0A    
 .bui
@@ -1851,11 +1851,14 @@
  %22/%3E
-%5Cn%22
+%22 + NL
 , ac
@@ -2049,39 +2049,32 @@
 er.newDocument()
-%0A      
 .element(element
@@ -2078,23 +2078,16 @@
 entName)
-%0A      
 .build()
@@ -2304,23 +2304,16 @@
 cument()
-%0A      
 .namespa
@@ -2350,23 +2350,16 @@
 _NS_URI)
-%0A      
 .element
@@ -2368,23 +2368,16 @@
 schema%22)
-%0A      
 .element
@@ -2388,16 +2388,18 @@
 ement%22)%0A
+  
       .a
@@ -2427,23 +2427,16 @@
 entName)
-%0A      
 .attribu
@@ -2455,23 +2455,16 @@
 string%22)
-%0A      
 .build()
@@ -2713,39 +2713,32 @@
 er.newDocument()
-%0A      
 .element(randomS
@@ -2738,39 +2738,32 @@
 randomString(8))
-%0A      
 .build();%0A    Do
@@ -3078,23 +3078,16 @@
 cument()
-%0A      
 .element
@@ -3103,23 +3103,16 @@
 ring(8))
-%0A      
 .build()

Fix test on Windows