/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.sdo.helper.classgen;

import java.io.File;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.sdo.helper.ClassBuffer;
import org.eclipse.persistence.sdo.helper.SDOClassGenerator;
import org.eclipse.persistence.testing.sdo.helper.xmlhelper.SDOXMLHelperTestCases;
import org.eclipse.persistence.testing.sdo.util.CompileUtil;

public abstract class SDOClassGenTestCases extends SDOXMLHelperTestCases {
    protected SDOClassGenerator classGenerator;
    protected String xsdString;
    /** Cache the packageNames ArrayList for memory performance improvement, fileNames should be optimized as well*/
    protected List<String> packageNames;

    public SDOClassGenTestCases(String name) {
        super(name);
    }

    @Override
    public void setUp() {
        super.setUp();
        File f = new File(getSourceFolder());
        emptyAndDeleteDirectory(f);

        xsdString = getSchema(getSchemaName());
        classGenerator = new SDOClassGenerator(aHelperContext);
    }

    @Override
    public void tearDown() throws Exception{
        super.tearDown();
        List<String> packages = getPackages();
        for (int i = 0; i < getFileNamesToCompile().size(); i++) {
            String nextFileName = getFileNamesToCompile().get(i);
            String nextPackageDir = packages.get(i);
            StringBuffer fullJavaName = new StringBuffer(getControlSourceFolder());
            fullJavaName.append("/");
            fullJavaName.append(nextPackageDir);
            fullJavaName.append("/");
            fullJavaName.append(nextFileName);
            File f = new File(fullJavaName.toString().replace(".java", ".class"));
            if(f.exists()){
              f.delete();
            }
        }
    }

    protected abstract String getSourceFolder();

    protected abstract String getControlSourceFolder();

    protected abstract String getSchemaName();

    protected abstract List<String> getControlFileNames();

    protected HashMap<String, String> getGeneratedFiles(Map<Object, ClassBuffer> generatedBuffers) {
        HashMap<String, String> generatedFiles = new HashMap<String, String>();

        Iterator<Object> keysIter = generatedBuffers.keySet().iterator();
        while (keysIter.hasNext()) {
            Object nextKey = keysIter.next();
            ClassBuffer next = generatedBuffers.get(nextKey);
            generatedFiles.put(Helper.getShortClassName(next.getSdoType().getInstanceClassName()) + ".java", next.getInterfaceBuffer().toString());
            generatedFiles.put(Helper.getShortClassName(next.getSdoType().getImplClassName()) +".java", next.getClassBuffer().toString());
        }

        return generatedFiles;
    }

    protected HashMap<String, String> getControlFiles() {
        HashMap<String, String> controlFiles = new HashMap<String, String>();
        List<String> controlFileNames = getControlFileNames();
        List<String> packages = getPackages();
        for (int i = 0; i < controlFileNames.size(); i++) {
            String nextFileName = controlFileNames.get(i);
            String nextPackageDir = packages.get(i);
            StringBuffer fullName = new StringBuffer(getControlSourceFolder());
            fullName.append("/");
            fullName.append(nextPackageDir);
            fullName.append("/");
            fullName.append(nextFileName);
            String classContents = getSchema(fullName.toString());
            controlFiles.put(nextFileName, classContents);
        }
        return controlFiles;
    }

    // Override package generation based on the JAXB 2.0 algorithm in SDOUtil.java
    protected List<String> getPackages() {
        if(null != packageNames && packageNames.size() > 0) {
            return packageNames;
        } else {
            packageNames = new ArrayList<String>();
            for(int i = 0;i < getControlFileNames().size();i++) {
                packageNames.add(NON_DEFAULT_JAVA_PACKAGE_DIR);
            }
        }
        return packageNames;
    }

    protected void compareFiles(HashMap<String, String> controlFiles, HashMap<String, String> generatedFiles) {
        assertEquals(controlFiles.size(), generatedFiles.size());
        Iterator<String> keysIter = controlFiles.keySet().iterator();
        while (keysIter.hasNext()) {
            String nextKey = keysIter.next();
            String nextControlValue = removeCopyrightFromString(controlFiles.get(nextKey));
            String nextGeneratedValue = generatedFiles.get(nextKey);
            assertNotNull(nextControlValue);
            assertNotNull(nextGeneratedValue);
            // convert ignoreCRLF
            assertStringsEqual(nextControlValue.trim(), nextGeneratedValue.trim());
        }
    }

    protected List<String> getFileNamesToCompile(){
        return getControlFileNames();
    }

    public void compileFiles(){
        Object[] javaFiles = new Object[getFileNamesToCompile().size()];
        List<String> packages = getPackages();
        for (int i = 0; i < getFileNamesToCompile().size(); i++) {
            String nextFileName = getFileNamesToCompile().get(i);
            String nextPackageDir = packages.get(i);
            StringBuffer fullName = new StringBuffer(getControlSourceFolder());
            fullName.append("/");
            fullName.append(nextPackageDir);
            fullName.append("/");
            fullName.append(nextFileName);
            javaFiles[i] = fullName.toString();
        }

        int returnVal = CompileUtil.instance().compile(classgenCompilePath, javaFiles);
        assertEquals(0, returnVal);
    }

    // The following test case is out of scope for ClassGenElements - we let it fail with a NPE that generates an empty xsdString for this suite
    public void testClassGen() throws Exception {
        //compileFiles(getControlSourceFolder() + "/" + getPackageDir());
        compileFiles();
        StringReader reader = new StringReader(xsdString);

        classGenerator.generate(reader, getSourceFolder());
        int numGenerated = classGenerator.getGeneratedBuffers().size();
        assertEquals(getControlFileNames().size() / 2, numGenerated);

        compareFiles(getControlFiles(), getGeneratedFiles(classGenerator.getGeneratedBuffers()));
    }
}
