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

import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlOptions;
import org.junit.Before;

import java.util.ArrayList;

public class BaseCase {
    protected boolean bVerbose = false;

    protected XmlOptions validateOptions;
    protected final ArrayList<XmlError> errorList = new ArrayList<>();

    @Before
    public void setUp() {
        validateOptions = new XmlOptions();
        errorList.clear();
        validateOptions.setErrorListener(errorList);
    }

    protected void clearErrors() {
        //reset error list for next time
        errorList.clear();
        validateOptions.setErrorListener(errorList);
    }

    public void showErrors() {
        if (bVerbose)
            for (XmlError error : errorList) {
                System.out.println("\n");
                System.out.println("Message: " + error.getMessage() + "\n");
                if (error.getCursorLocation() != null) {
                    System.out.println("Location of invalid XML: " + error.getCursorLocation().xmlText() + "\n");
                }
            }

    }

    //TODO: compare regardless of order
    public boolean compareErrorCodes(String[] expected) {
        if ( errorList.size() != expected.length){
            System.err.println(stringOfCodes(expected,errorList));

           return false;
        }
        StringBuilder errMessage = new StringBuilder();
        for (int i = 0; i < errorList.size(); i++) {
            XmlError error = (XmlError) errorList.get(i);
            if ( error.getErrorCode() == null )
              errMessage.append("Kevin needs a code here "+error.getMessage()+"\n");

            if (!expected[i].equals(error.getErrorCode())){
                if (errMessage.length() > 0)
                    System.err.println(errMessage);
                ArrayList exp=new ArrayList();

                System.err.println(stringOfCodes(expected,errorList));
                return false;
            }
        }
        return true;
    }

    public String stringOfCodes(String[] errorCodes, ArrayList actual_errorCodes)
    {
        StringBuilder res = new StringBuilder();
        res.append("\n Expected codes:\n");
        int i=0;
        for (;i < errorCodes.length; i++ )
            res.append( errorCodes[i]+"\n" );
        res.append("\nBut Got: \n");
        for ( i=0 ;i < actual_errorCodes.size(); i++ )
            res.append( actual_errorCodes.get(i)+"\n" );

        return res.toString();
    }

}
