/*   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 tools.inst2xsd.common;

import common.Common;
import org.apache.xmlbeans.*;
import org.apache.xmlbeans.impl.inst2xsd.Inst2Xsd;
import org.apache.xmlbeans.impl.inst2xsd.Inst2XsdOptions;
import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
import tools.xml.XmlComparator;

import java.util.ArrayList;
import java.util.Collection;

import static org.junit.Assert.assertNotNull;

public class Inst2XsdTestBase extends Common {

    public static tools.inst2xsd.common.Inst2XsdCommon common;
    private static boolean _verbose = true;

    private static String caseroot = XBEAN_CASE_ROOT;
    //location of files under "cases folder"
    private static String miscDir = caseroot + P + "tools";
    private static String inst2xsdDir = miscDir + P + "inst2xsd" + P;
    protected static String OPTION_CASES_DIR = inst2xsdDir + P + "options" + P;
    protected static String SCHEMA_CASES_DIR = inst2xsdDir + P + "schema" + P;
    protected static final String BASEXML = OPTION_CASES_DIR + "base.xml";
    protected static final String EXPBASEXML = OPTION_CASES_DIR + "base0.xsd";


    protected XmlObject getTypeXml(String val) throws Exception {
        return XmlObject.Factory.parse(setTypeVal(val));
    }

    private String setTypeVal(String val) {
        String base_start = "<a xmlns=\"typeTests\">";
        String base_end = "</a>";
        return base_start + val + base_end;
    }

    protected XmlObject getAttrTypeXml(String val) throws Exception {
        return XmlObject.Factory.parse(setAttrVal(val));
    }

    private String setAttrVal(String val) {
        String attr_base_end = "\" />";
        String attr_base_start = "<a xmlns=\"attrTests\" a=\"";
        return attr_base_start + val + attr_base_end;
    }

    //attribute testing methods

    private String getAttrTypeXmlVenetian(String type) {
        return "<schema attributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\" " +
               "targetNamespace=\"attrTests\" xmlns=\"http://www.w3.org/2001/XMLSchema\">" +
               "<element name=\"a\" type=\"att:aType\" xmlns:att=\"attrTests\"/>" +
               "<complexType name=\"aType\">" +
               "<simpleContent>" +
               "<extension base=\"xs:string\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">" +
               "<attribute type=\"xs:" + type + "\" name=\"a\"/>" +
               "</extension>" +
               "</simpleContent></complexType></schema>";
    }

    private String getAttrTypeXmlRDandSS(String type) {
        return "<schema attributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\" " +
               "targetNamespace=\"attrTests\" xmlns=\"http://www.w3.org/2001/XMLSchema\">" +
               "<element name=\"a\">" +
               "<complexType>" +
               "<simpleContent>" +
               "<extension base=\"xs:string\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">" +
               "<attribute type=\"xs:" + type + "\" name=\"a\"/>" +
               "</extension>" +
               "</simpleContent>" +
               "</complexType></element></schema>";
    }

    protected void runAttrTypeChecking(XmlObject act, String expType) throws Exception {

        log("=== Venetian options ===");
        runAttrTypeChecking(act, expType, Inst2XsdCommon.getVenetianOptions());
        log("=== Russian options ===");
        runAttrTypeChecking(act, expType, Inst2XsdCommon.getRussianOptions());
        log("=== Salami options ===");
        runAttrTypeChecking(act, expType, Inst2XsdCommon.getSalamiOptions());
        log("=== Default options ===");
        runAttrTypeChecking(act, expType, Inst2XsdCommon.getDefaultInstOptions());
    }

    private void runAttrTypeChecking(XmlObject act, String expType, Inst2XsdOptions opt) throws Exception {
        SchemaDocument[] venetian = (SchemaDocument[]) runInst2Xsd(act, opt);
        checkLength(venetian, 1);

        if (opt.getDesign() == Inst2XsdOptions.DESIGN_RUSSIAN_DOLL ||
            opt.getDesign() == Inst2XsdOptions.DESIGN_SALAMI_SLICE)
            compare(venetian[0], XmlObject.Factory.parse(getAttrTypeXmlRDandSS(expType)));
        else if (opt.getDesign() == Inst2XsdOptions.DESIGN_VENETIAN_BLIND)
            compare(venetian[0], XmlObject.Factory.parse(getAttrTypeXmlVenetian(expType)));
        else
            throw new Exception("Design style was not found");

        checkInstance(venetian, new XmlObject[]{act});

    }

    //element value test methods
    protected void runTypeChecking(XmlObject act, String expType) throws Exception {
        log("=== Venetian options ===");
        runTypeChecking(act, expType, Inst2XsdCommon.getVenetianOptions());
        log("=== Russian options ===");
        runTypeChecking(act, expType, Inst2XsdCommon.getRussianOptions());
        log("=== Salami options ===");
        runTypeChecking(act, expType, Inst2XsdCommon.getSalamiOptions());
        log("=== Default options ===");
        runTypeChecking(act, expType, Inst2XsdCommon.getDefaultInstOptions());
    }


    private void runTypeChecking(XmlObject act, String expType, Inst2XsdOptions opt) throws Exception {
        SchemaDocument[] venetian = (SchemaDocument[]) runInst2Xsd(act, opt);
        checkLength(venetian, 1);
        log("actual: " + act);
        log("expType: " + expType);
        checkInstance(venetian, new XmlObject[]{act});
        compare(venetian[0], XmlObject.Factory.parse(getExpTypeXml(expType)));
    }

    private String getExpTypeXml(String type) {
        return "<xs:schema attributeFormDefault=\"unqualified\" " +
               "elementFormDefault=\"qualified\" targetNamespace=\"typeTests\"" +
               " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" >" +
               "<xs:element name=\"a\" type=\"xs:" + type + "\"" +
               " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />" +
               "</xs:schema>";
    }

    //type coercion/LCD test methods
    protected void runLCDTypeCheckTest(String val1, String val2, String expType) throws Exception {
        log("=== Venetian options ===");
        runLCDTypeChecking(val1, val2, expType, Inst2XsdCommon.getVenetianOptions());
        log("=== Russian options ===");
        runLCDTypeChecking(val1, val2, expType, Inst2XsdCommon.getRussianOptions());
        log("=== Salami options ===");
        runLCDTypeChecking(val1, val2, expType, Inst2XsdCommon.getSalamiOptions());
        log("=== Default options ===");
        runLCDTypeChecking(val1, val2, expType, Inst2XsdCommon.getDefaultInstOptions());
    }

    private void runLCDTypeChecking(String val1, String val2, String expType, Inst2XsdOptions opt) throws Exception {
        XmlObject act = getTypeCoerceXml(val1, val2);
        SchemaDocument[] venetian = (SchemaDocument[]) runInst2Xsd(act, opt);
        checkLength(venetian, 1);
        log("instance: " + act);
        log("expType: " + expType);
        checkInstance(venetian, new XmlObject[]{act});

        if (opt.getDesign() == Inst2XsdOptions.DESIGN_VENETIAN_BLIND)
            compare(venetian[0], getExpLCDXml_vb(expType));
        else if (opt.getDesign() == Inst2XsdOptions.DESIGN_SALAMI_SLICE)
            compare(venetian[0], getExpLCDXml_ss(expType));
        else if (opt.getDesign() == Inst2XsdOptions.DESIGN_RUSSIAN_DOLL)
            compare(venetian[0], getExpLCDXml_rd(expType));
        else
            compare(venetian[0], getExpLCDXml_vb(expType));
    }

    private String getTypeCoerceXmlString(String val1, String val2) {
        return "<a xmlns=\"typeCoercion\">" +
               "    <b c=\"" + val1 + "\">" + val1 + "</b>" +
               "    <b c=\"" + val2 + "\">" + val2 + "</b>" +
               "</a>";
    }

    private XmlObject getTypeCoerceXml(String val1, String val2) throws XmlException {
        return XmlObject.Factory.parse(getTypeCoerceXmlString(val1, val2));
    }


    private XmlObject getExpLCDXml_vb(String type) throws XmlException {
        return XmlObject.Factory.parse("<xs:schema attributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\" targetNamespace=\"typeCoercion\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" +
                                       "  <xs:element name=\"a\" type=\"typ:aType\" xmlns:typ=\"typeCoercion\"/>\n" +
                                       "  <xs:complexType name=\"aType\">\n" +
                                       "    <xs:sequence>\n" +
                                       "      <xs:element type=\"typ:bType\" name=\"b\" maxOccurs=\"unbounded\" minOccurs=\"0\" xmlns:typ=\"typeCoercion\"/>\n" +
                                       "    </xs:sequence>\n" +
                                       "  </xs:complexType>\n" +
                                       "  <xs:complexType name=\"bType\">\n" +
                                       "    <xs:simpleContent>\n" +
                                       "      <xs:extension base=\"xs:" + type + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" +
                                       "        <xs:attribute type=\"xs:" + type + "\" name=\"c\" use=\"optional\"/>\n" +
                                       "      </xs:extension>\n" +
                                       "    </xs:simpleContent>\n" +
                                       "  </xs:complexType>\n" +
                                       "</xs:schema>");
    }

    private XmlObject getExpLCDXml_ss(String type) throws XmlException {
        return XmlObject.Factory.parse("<xs:schema attributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\" targetNamespace=\"typeCoercion\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" +
                                       "  <xs:element name=\"b\">\n" +
                                       "    <xs:complexType>\n" +
                                       "      <xs:simpleContent>\n" +
                                       "        <xs:extension base=\"xs:" + type + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" +
                                       "          <xs:attribute type=\"xs:" + type + "\" name=\"c\" use=\"optional\"/>\n" +
                                       "        </xs:extension>\n" +
                                       "      </xs:simpleContent>\n" +
                                       "    </xs:complexType>\n" +
                                       "  </xs:element>\n" +
                                       "  <xs:element name=\"a\">\n" +
                                       "    <xs:complexType>\n" +
                                       "      <xs:sequence>\n" +
                                       "        <xs:element ref=\"typ:b\" maxOccurs=\"unbounded\" minOccurs=\"0\" xmlns:typ=\"typeCoercion\"/>\n" +
                                       "      </xs:sequence>\n" +
                                       "    </xs:complexType>\n" +
                                       "  </xs:element>\n" +
                                       "</xs:schema>");
    }

    private XmlObject getExpLCDXml_rd(String type) throws XmlException {
        return XmlObject.Factory.parse("<xs:schema attributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\" targetNamespace=\"typeCoercion\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" +
                                       "  <xs:element name=\"a\">\n" +
                                       "    <xs:complexType>\n" +
                                       "      <xs:sequence>\n" +
                                       "        <xs:element name=\"b\" maxOccurs=\"unbounded\" minOccurs=\"0\">\n" +
                                       "          <xs:complexType>\n" +
                                       "            <xs:simpleContent>\n" +
                                       "              <xs:extension base=\"xs:" + type + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" +
                                       "                <xs:attribute type=\"xs:" + type + "\" name=\"c\" use=\"optional\"/>\n" +
                                       "              </xs:extension>\n" +
                                       "            </xs:simpleContent>\n" +
                                       "          </xs:complexType>\n" +
                                       "        </xs:element>\n" +
                                       "      </xs:sequence>\n" +
                                       "    </xs:complexType>\n" +
                                       "  </xs:element>\n" +
                                       "</xs:schema>");
    }


    protected static XmlObject[] runInst2Xsd(XmlObject inst, Inst2XsdOptions options) {
        return Inst2Xsd.inst2xsd(new XmlObject[]{inst}, options);
    }

    protected static XmlObject[] runInst2Xsd(XmlObject[] inst, Inst2XsdOptions options) {
        return Inst2Xsd.inst2xsd(inst, options);
    }


    protected static SchemaDocument[] getSchemaDoc(XmlObject[] inst) throws XmlException {
        SchemaDocument[] docs = new SchemaDocument[inst.length];
        for (int i = 0; i < docs.length; i++) {
            docs[i] = SchemaDocument.Factory.parse(inst[i].xmlText());
        }
        return docs;

    }

    protected static void runSchemaBuild(XmlObject inst, Inst2XsdOptions opts, XmlObject exp) throws Exception {
        XmlObject[] genSchema = runInst2Xsd(inst, opts);
        log(genSchema);
        checkInstanceToAll(genSchema, inst, exp);
        checkLength(genSchema, 1);
        compare(genSchema[0], exp);

    }

    protected static void runSchemaBuild(XmlObject inst, Inst2XsdOptions opts, XmlObject[] exp) throws XmlException {
        XmlObject[] genSchema = runInst2Xsd(inst, opts);
        log(genSchema);
        checkInstanceToAll(genSchema, new XmlObject[]{inst}, exp);
        checkLength(genSchema, exp.length);
        compare(genSchema, exp);

    }

    //TODO: Make this error narrowed
    protected static void checkLength(Object[] obj, int val) throws XmlException {
        log("Length = " + obj.length + " exp: " + val);

        if (obj.length < val) {
            throw new XmlException("Actual was smaller than expected");
        } else if (obj.length > val) {
            throw new XmlException("Actual was larger than expected");
        }
    }


    public static void compare(XmlObject[] act, XmlObject[] exp) throws XmlException {
        checkLength(act, exp.length);
        //Arrays.sort(act);
        //Arrays.sort(exp);
        //if (Arrays.equals(act, exp)){
        //    return;
        //}else{
        for (int i = 0; i < act.length; i++) {
            compare(act[i], exp[i]);
        }

    }

    public static void compare(XmlObject act, XmlObject exp) throws XmlException {
        XmlComparator.Diagnostic diag = XmlComparator.lenientlyCompareTwoXmlStrings(act.xmlText(Inst2XsdCommon.getXmlOptions()),
            exp.xmlText(Inst2XsdCommon.getXmlOptions()));
        if (diag.hasMessage()) {
            log("Expected: \n" + exp.xmlText(Inst2XsdCommon.getXmlOptions()));
            log("Actual: \n" + act.xmlText(Inst2XsdCommon.getXmlOptions()));
            throw new XmlException("Xml Comparison Failed:\n" + diag.toString());
        }
    }

    public static void log(XmlObject[] doc) {
        if (_verbose) {
            for (int i = 0; i < doc.length; i++) {
                log("Schema[" + i + "] - " + doc[i].xmlText(Inst2XsdCommon.getXmlOptions()));
            }
        }
    }

    public static void log(String msg) {
        if (_verbose)
            System.out.println(msg);
    }

    public static void log(XmlObject obj) {
        if (_verbose)
            System.out.println(obj.xmlText(Inst2XsdCommon.getXmlOptions()));
    }


    private static void checkInstanceToAll(XmlObject[] actSchemaDoc, XmlObject inst,
                                           XmlObject expSchemas) throws Exception {
        checkInstanceToAll(getSchemaDoc(actSchemaDoc), new XmlObject[]{inst}, getSchemaDoc(new XmlObject[]{expSchemas}));
    }

    private static void checkInstanceToAll(XmlObject[] actSchemaDoc, XmlObject[] inst,
                                           XmlObject[] expSchemas) throws XmlException {
        checkInstanceToAll(getSchemaDoc(actSchemaDoc), inst, getSchemaDoc(expSchemas));
    }

    private static void checkInstanceToAll(SchemaDocument[] actSchemaDoc, XmlObject[] inst,
                                           SchemaDocument[] expSchemas) throws XmlException {
        log("-= Comparing Actual to instance=-");
        if (checkInstance(actSchemaDoc, inst))
            log("-= Instance validated actual =-");

        log("-= Comparing Expected to instance=-");
        if (checkInstance(expSchemas, inst))
            log("-= Instance validated Expected =-");

    }

    private static boolean checkInstance(SchemaDocument[] sDocs, XmlObject[] inst) throws XmlException {
        if (validateInstances(sDocs, inst)) {
            return true;
        } else {
            throw new XmlException("Instance Failed to validate");
        }
    }

    /**
     * Copied from inst2Xsd as option may be removed
     */
    private static boolean validateInstances(SchemaDocument[] sDocs, XmlObject[] instances) {

        SchemaTypeLoader sLoader;
        Collection compErrors = new ArrayList();
        XmlOptions schemaOptions = new XmlOptions();
        schemaOptions.setErrorListener(compErrors);
        try {
            sLoader = XmlBeans.loadXsd(sDocs, schemaOptions);
        } catch (Exception e) {
            if (compErrors.isEmpty() || !(e instanceof XmlException)) {
                e.printStackTrace(System.out);
            }
            System.out.println("Schema invalid");
            for (Object compError : compErrors) System.out.println(compError);
            return false;
        }

        boolean result = true;

        for (int i = 0; i < instances.length; i++) {
            String instance = instances[i].toString();

            XmlObject xobj;

            try {
                assertNotNull(sLoader);
                xobj = sLoader.parse(instance, null, new XmlOptions().setLoadLineNumbers());
            } catch (XmlException e) {
                System.out.println("Error:\n" + instance + " not loadable: " + e);
                e.printStackTrace(System.out);
                result = false;
                continue;
            }

            Collection errors = new ArrayList();

            if (xobj.schemaType() == XmlObject.type) {
                System.out.println(instance + " NOT valid.  ");
                System.out.println("  Document type not found.");
                result = false;
            } else if (xobj.validate(new XmlOptions().setErrorListener(errors)))
                System.out.println("Instance[" + i + "] valid.");
            else {
                System.out.println("Instance[" + i + "] NOT valid.");
                for (Object error : errors) {
                    System.out.println("    " + error);
                }
                result = false;
            }
        }

        return result;
    }

}
