/*
 * 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
//     04/01/2011-2.3 Guy Pelletier
//       - 337323: Multi-tenant with shared schema support (part 2)
package org.eclipse.persistence.tools.weaving.jpa;

import java.io.IOException;
import java.io.Writer;
import java.lang.instrument.IllegalClassFormatException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipException;

import jakarta.persistence.spi.ClassTransformer;

import org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl;
import org.eclipse.persistence.internal.jpa.StaticWeaveInfo;
import org.eclipse.persistence.internal.jpa.deployment.ArchiveFactoryImpl;
import org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor;
import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.exceptions.PersistenceUnitLoadingException;
import org.eclipse.persistence.exceptions.StaticWeaveException;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.jpa.Archive;

/**
* <p>
* <b>Description</b>: This class provides the implementation of class transformer by leveraging on the following existing APIs,
* <ul>
* <li> PersistenceUnitProcessor.processORMetadata() - get class descriptor.
* <li> PersistenceUnitProcessor.buildEntityList() - get entity classes lsit.
* <li> TransformerFactory.createTransformerAndModifyProject - get class transformer.
* </ul>
* <p>
* <b>Responsibilities</b>:
* <ul>
* <li> Create the classtransformer for each persistence unit individually and store them into the list.
* <li> Provide class transfom method to perform weaving function.
* </ul>
*/

public class StaticWeaveClassTransformer {
    private ArrayList<ClassTransformer> classTransformers;
    StaticWeaveInfo info;
    private ClassLoader aClassLoader;

    /**
     * Constructs an instance of StaticWeaveClassTransformer.
     */
    public StaticWeaveClassTransformer(URL inputArchiveURL,ClassLoader aclassloader) throws Exception {
        this(inputArchiveURL,null, aclassloader,null,SessionLog.OFF);
    }

    /**
     * Constructs an instance of StaticWeaveClassTransformer.
     */
    public StaticWeaveClassTransformer(URL inputArchiveURL, String persistenceXMLLocation, ClassLoader aclassloader, Writer logWriter, int loglevel) throws URISyntaxException,IOException {
        this.aClassLoader = aclassloader;
        this.info = new StaticWeaveInfo(logWriter, loglevel);
        buildClassTransformers(inputArchiveURL, persistenceXMLLocation, aclassloader);
    }

    /**
     * The method performs weaving function on the given class.
     * @return the converted(woven) class
     */
    public byte[] transform(String originalClassName, Class originalClass, byte[] originalClassBytes)throws IllegalClassFormatException{
        byte[] newClassBytes = null;
        for(ClassTransformer transformer : classTransformers){
            newClassBytes=transformer.transform(aClassLoader, originalClassName, originalClass, null, originalClassBytes);
            if(newClassBytes!=null) {
                break;
            };
        }
        return newClassBytes;
    }

    /**
     * The method creates classtransformer list corresponding to each persistence unit.
     */
    private void buildClassTransformers(URL inputArchiveURL, String persistenceXMLLocation, ClassLoader aclassloader) throws URISyntaxException,IOException{
        if (classTransformers!=null) {
            return ;
        } else {
            classTransformers = new ArrayList<ClassTransformer>();
        }
        Archive archive = null;
        try {

            archive = (new ArchiveFactoryImpl()).createArchive(inputArchiveURL, persistenceXMLLocation == null ? PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML_DEFAULT : persistenceXMLLocation, null);

            List<SEPersistenceUnitInfo> persistenceUnitsList =
            PersistenceUnitProcessor.processPersistenceArchive(archive, aclassloader);
            if (persistenceUnitsList==null) {
                throw PersistenceUnitLoadingException.couldNotGetUnitInfoFromUrl(inputArchiveURL);
            }
            Map<Object, Object> emptyMap = new HashMap<>(0);
            Iterator<SEPersistenceUnitInfo> persistenceUnitsIterator = persistenceUnitsList.iterator();
            while (persistenceUnitsIterator.hasNext()) {
                SEPersistenceUnitInfo unitInfo = persistenceUnitsIterator.next();
                //build class transformer.
                String puName = unitInfo.getPersistenceUnitName();
                String sessionName = (String)unitInfo.getProperties().get(PersistenceUnitProperties.SESSION_NAME);
                if (sessionName == null) {
                    sessionName = puName;
                }
                EntityManagerSetupImpl emSetupImpl = new EntityManagerSetupImpl(puName, sessionName);
                //indicates that predeploy is used for static weaving, also passes logging parameters
                emSetupImpl.setStaticWeaveInfo(this.info);
                ClassTransformer transformer = emSetupImpl.predeploy(unitInfo, emptyMap);
                if (transformer != null) {
                    classTransformers.add(transformer);
                }
            }
        } catch (ZipException e) {
            throw StaticWeaveException.exceptionOpeningArchive(inputArchiveURL,e);
        } finally {
            if (archive != null) {
                archive.close();
            }
        }
    }
}
