/*
 * Copyright (c) 1998, 2020 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.class.cast(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;
        }
    }
}
