/*   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.checkin;

import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.SimpleValue;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException;
import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class LengthFacetValidateOnSetTest {

    private static SimpleValue rootWithValidateOnSet(String base) throws Exception {
        String xsd =
            "<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' " +
            "xmlns:t='urn:t' targetNamespace='urn:t' elementFormDefault='qualified'>" +
            "  <xs:element name='root'>" +
            "    <xs:simpleType>" +
            "      <xs:restriction base='" + base + "'>" +
            "        <xs:length value='5'/>" +
            "      </xs:restriction>" +
            "    </xs:simpleType>" +
            "  </xs:element>" +
            "</xs:schema>";

        SchemaTypeLoader loader = XmlBeans.loadXsd(new XmlObject[]{SchemaDocument.Factory.parse(xsd)});
        XmlOptions options = new XmlOptions().setValidateOnSet();
        XmlObject doc = loader.parse("<t:root xmlns:t='urn:t'>abcde</t:root>", null, options);
        try (XmlCursor c = doc.newCursor()) {
            c.toFirstChild();
            return (SimpleValue) c.getObject();
        }
    }

    @Test
    void anyUriLengthFacetOnSet() throws Exception {
        SimpleValue root = rootWithValidateOnSet("xs:anyURI");
        // a value whose length matches the length facet must be accepted
        assertDoesNotThrow(() -> root.setStringValue("xyzab"));
        // a value whose length does not match must be rejected
        assertThrows(XmlValueOutOfRangeException.class, () -> root.setStringValue("xyz"));
    }
}
