/*
 *   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package misc.detailed;

import jira.xmlbeans228.substitution.CommentType;
import jira.xmlbeans228.substitution.FirstCommentType;
import jira.xmlbeans228.substitution.PersonDocument;
import misc.common.JiraTestBase;
import misc.detailed.jira208.FrogBreathDocument;
import org.apache.xmlbeans.XmlOptions;
import org.junit.Test;

import javax.xml.namespace.QName;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static org.junit.Assert.*;

public class JiraRegression201_250Test extends JiraTestBase {

    /*
    * [XMLBEANS-206]: Wrong method finding in getMethod() of InterfaceExtensionImpl
    *
    */
    // Refer test case xmlobject.extensions.interfaceFeature.averageCase.checkin.testJiraXMLBEANS_206

    /*
    * [XMLBEANS-208]: validation of decimal with fractionDigits -- special case, additional zero digits
    *
    */
    @Test
    public void test_jira_xmlbeans208() throws Exception {

        XmlOptions options = new XmlOptions();
        List err = new ArrayList();
        options.setErrorListener(err);

        // decimal value invalid
        FrogBreathDocument invalidDoc = FrogBreathDocument.Factory.parse("<dec:frog_breath xmlns:dec=\"http://misc/detailed/jira208\">1000.000001</dec:frog_breath>");
        boolean valid = invalidDoc.validate(options);
        if(!valid)
        {
            for (Iterator iterator = err.iterator(); iterator.hasNext();) {
                System.out.println("Validation Error (invalid doc):" + iterator.next());
            }
        }
        // expected to fail
        assertFalse(valid);

        // decimal value with trailing zeros tagged as invalid
        FrogBreathDocument validDoc = FrogBreathDocument.Factory.parse("<dec:frog_breath xmlns:dec=\"http://misc/detailed/jira208\">1000.000000</dec:frog_breath>");

        err.clear();
        boolean valid2 = validDoc.validate(options);
        if(!valid2)
        {
            for (Iterator iterator = err.iterator(); iterator.hasNext();) {
                System.out.println("Validation Error (valid doc):" + iterator.next());
            }
        }

        assertTrue(valid2);
    }

    /*
    * [XMLBEANS-228]: 
    * element order in sequence incorrect after calling substitute()
    */
    @Test
    public void test_jira_xmlbeans228() throws Exception
    {
        PersonDocument personDocument = PersonDocument.Factory.newInstance();
        PersonDocument.Person person = personDocument.addNewPerson();
        CommentType commentType = person.addNewComment();
        String ns = "http://jira/xmlbeans_228/substitution";
        QName qName = new QName(ns, "FirstCommentElement");
        Object resultObject = commentType.substitute(qName, FirstCommentType.type);
        FirstCommentType firstCommentType = (FirstCommentType)resultObject;
        firstCommentType.setStringValue("ThirdElement");
        person.setComment(firstCommentType);
        
        person.setFirstName("FirstElement");
        person.setLastName("SecondElement");
        
        XmlOptions opts = new XmlOptions().setSavePrettyPrint().setUseDefaultNamespace();
        StringWriter out = new StringWriter();
        personDocument.save(out, opts);

        String exp = 
            "<Person xmlns=\"http://jira/xmlbeans_228/substitution\">" + NEWLINE +
            "  <FirstName>FirstElement</FirstName>" + NEWLINE +
            "  <LastName>SecondElement</LastName>" + NEWLINE +
            "  <FirstCommentElement>ThirdElement</FirstCommentElement>" + NEWLINE +
            "</Person>";

        assertEquals(exp, out.toString());
        if (!personDocument.validate())
        {
            fail("Wrong element order!");
        }
    }
}
