/*
 * 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.internal.jpa.deployment;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.logging.Logger;
import java.util.logging.Level;

import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.jpa.Archive;
import org.eclipse.persistence.jpa.ArchiveFactory;

/**
 * This class is written to deal with various URLs that can be returned by
 * {@link jakarta.persistence.spi.PersistenceUnitInfo#getPersistenceUnitRootUrl()}
 *
 * @author Sanjeeb.Sahoo@Sun.COM
 */
public class ArchiveFactoryImpl implements ArchiveFactory {

    /*
     * Implementation Note: This class does not have any dependency on either
     * EclipseLink or GlassFish implementation classes. Please retain this separation.
     */

    protected Logger logger;

    @SuppressWarnings("deprecation")
    public ArchiveFactoryImpl() {
        this(Logger.global);
    }

    public ArchiveFactoryImpl(Logger logger) {
        this.logger = logger;
    }

    @Override
    public Archive createArchive(URL rootUrl, Map properties) throws URISyntaxException, IOException {
        return createArchive(rootUrl, null, properties);
    }

    @Override
    public Archive createArchive(URL rootUrl, String descriptorLocation, Map properties) throws URISyntaxException, IOException {
        logger.entering("ArchiveFactoryImpl", "createArchive", new Object[]{rootUrl, descriptorLocation});

        if (rootUrl == null) {
            return null;
        }

        Archive result = null;
        String protocol = rootUrl.getProtocol();
        logger.logp(Level.FINER, "ArchiveFactoryImpl", "createArchive", "protocol = {0}", protocol);

        if ("file".equals(protocol)) {
            URI uri = Helper.toURI(rootUrl);

            File f;
            try {
                // Attempt to create the file with the uri. The pre-conditions
                // are checked in the constructor and an exception is thrown
                // if the uri does not meet them.
                f = new File(uri);
            } catch (IllegalArgumentException e) {
                // Invalid uri for File. Go our back up route of using the
                // path from the url.
                f = new File(rootUrl.getPath());
            }

            if (f.isDirectory()) {
                // e.g. file:/tmp/a_ear/ejb_jar
                result = new DirectoryArchive(f, descriptorLocation);
            } else {
                // e.g. file:/tmp/a_ear/lib/pu.jarlo
                // It's not a directory. Then it must be a jar file.
                result = new JarFileArchive(rootUrl, new JarFile(f), descriptorLocation);
            }
        } else if ("jar".equals(protocol)) { // NOI18N
            JarURLConnection conn = (JarURLConnection) rootUrl.openConnection();
            conn.setUseCaches(false);
            JarEntry je = conn.getJarEntry();
            if (je == null) {
                // e.g. jar:file:/tmp/a_ear/lib/pu.jar!/
                // No entryName specified, hence URL points to a JAR file and
                // not to any entry inside it. Ideally this should have been
                // file:/tmp/a_ear/lib/pu.jar,
                // but containers (e.g.) WebLogic return this kind of URL,
                // so we better handle this in our code to improve pluggability.
                // Read the entire jar file.
                result = new JarFileArchive(rootUrl, conn.getJarFile(), descriptorLocation);
            } else if (je.isDirectory()) {
                // e.g. jar:file:/tmp/a_ear/b.war!/WEB-INF/classes/
                // entryName [je.getName()] is a directory
                result = new DirectoryInsideJarURLArchive(rootUrl, descriptorLocation);
            } else {
                // some URL (e.g.) jar:file:/tmp/a_ear/b.war!/WEB-INF/lib/pu.jar
                // entryName [je.getName()] is a file, so treat this URL as a
                // URL from which  a JAR format InputStream can be obtained.
                result = new JarInputStreamURLArchive(rootUrl, descriptorLocation);
            }
        } else if (isJarInputStream(rootUrl)){
            result = new JarInputStreamURLArchive(rootUrl, descriptorLocation);
        } else {
            result = new URLArchive(rootUrl, descriptorLocation);
        }
        logger.exiting("ArchiveFactoryImpl", "createArchive", result);
        return result;
    }

    /**
     * This method is called for a URL which has neither jar nor file protocol.
     * This attempts to find out if we can treat it as a URL from which a JAR
     * format InputStream can be obtained.
     * @param url
     */
    protected boolean isJarInputStream(URL url) throws IOException {
        InputStream in = null;
        try {
            in = url.openStream();
            if (in == null) { // for directories, we may get InputStream as null
                return false;
            }
            JarInputStream jis = null;
            try {
                jis = new JarInputStream(in);
                if (jis.getNextEntry() == null){// if there is no next entry, this jar stream can't be used
                    return false;
                }
                return true; // we are successful in creating a Jar format IS
            } finally {
                if (jis != null){
                    jis.close();
                }
            }

        } catch (IOException ioe) {
            if (in != null) {
                in.close();
            }
            return false;
        }
    }
}
