/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.felix.framework.cache;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;

import org.apache.felix.framework.Logger;
import org.apache.felix.framework.util.WeakZipFileFactory;
import org.osgi.framework.connect.ConnectContent;

public class ConnectContentContent implements Content
{
    private static final transient String EMBEDDED_DIRECTORY = "-embedded";
    private static final transient String LIBRARY_DIRECTORY = "-lib";

    private final Logger m_logger;
    private final WeakZipFileFactory m_zipFactory;
    private final Map m_configMap;
    private final String m_name;
    private final File m_rootDir;
    private final Object m_revisionLock;
    private final ConnectContent m_content;

    public ConnectContentContent(Logger logger, WeakZipFileFactory zipFactory, Map configMap, String name, File rootDir, Object revisionLock, ConnectContent content) throws IOException
    {
        m_logger = logger;
        m_zipFactory = zipFactory;
        m_configMap = configMap;
        m_name = name;
        m_rootDir = rootDir;
        m_revisionLock = revisionLock;
        m_content = content;
    }

    @Override
    public void close()
    {
        // TODO: Connect
    }

    @Override
    public boolean hasEntry(String name)
    {
        return m_content.getEntry(name).isPresent();
    }

    @Override
    public boolean isDirectory(String name)
    {
        return m_content.getEntry(name).map(entry -> entry.getName().endsWith("/")).orElse(false);
    }

    @Override
    public Enumeration<String> getEntries()
    {
        try
        {
            Iterator<String> entries = m_content.getEntries().iterator();
            return new Enumeration<String>()
            {
                @Override
                public boolean hasMoreElements()
                {
                    return entries.hasNext();
                }

                @Override
                public String nextElement()
                {
                    return entries.next();
                }
            };
        }
        catch (IOException e)
        {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public byte[] getEntryAsBytes(String name)
    {
        return m_content.getEntry(name).flatMap(entry ->
        {
            try
            {
                return Optional.of(entry.getBytes());
            }
            catch (IOException e)
            {
                e.printStackTrace();
                return null;
            }
        }).orElse(null);
    }

    @Override
    public InputStream getEntryAsStream(String name) throws IOException
    {
        return m_content.getEntry(name).flatMap(entry ->
        {
            try
            {
                return Optional.of(entry.getInputStream());
            }
            catch (IOException e)
            {
                e.printStackTrace();
                return null;
            }
        }).orElse(null);
    }

    public ClassLoader getClassLoader() {
        return m_content.getClassLoader().orElse(null);
    }

    @Override
    public Content getEntryAsContent(String name)
    {
        if (".".equals(name) || "".equals(name))
        {
            return this;
        }
        String dir = name.endsWith("/") ? name : name + "/";

        if (hasEntry(dir))
        {
            return new ContentDirectoryContent(this, name);
        }

        if (hasEntry(name) && name.endsWith(".jar"))
        {
            // Any embedded JAR files will be extracted to the embedded directory.
            // Since embedded JAR file names may clash when extracting from multiple
            // embedded JAR files, the embedded directory is per embedded JAR file.
            File embedDir = new File(m_rootDir, m_name + EMBEDDED_DIRECTORY);

            File extractJar = new File(embedDir, name);

            try
            {
                if (!BundleCache.getSecureAction().fileExists(extractJar))
                {
                    // Extracting the embedded JAR file impacts all other existing
                    // contents for this revision, so we have to grab the revision
                    // lock first before trying to extract the embedded JAR file
                    // to avoid a race condition.
                    synchronized (m_revisionLock)
                    {
                        if (!BundleCache.getSecureAction().fileExists(extractJar))
                        {
                            // Make sure that the embedded JAR's parent directory exists;
                            // it may be in a sub-directory.
                            File jarDir = extractJar.getParentFile();
                            if (!BundleCache.getSecureAction().fileExists(jarDir) && !BundleCache.getSecureAction().mkdirs(jarDir))
                            {
                                throw new IOException("Unable to create embedded JAR directory.");
                            }

                            // Extract embedded JAR into its directory.
                            BundleCache.copyStreamToFile(m_content.getEntry(name).get().getInputStream(), extractJar);
                        }
                    }
                }
                return new JarContent(
                    m_logger, m_configMap, m_zipFactory, m_revisionLock,
                    extractJar.getParentFile(), extractJar, null);
            }
            catch (Exception ex)
            {
                m_logger.log(
                    Logger.LOG_ERROR,
                    "Unable to extract embedded JAR file.", ex);
            }
        }

        return null;
    }

    @Override
    public String getEntryAsNativeLibrary(String entryName)
    {
        // TODO: Connect
        return null;
    }

    @Override
    public URL getEntryAsURL(String name)
    {
        // TODO: Connect
        return null;
    }

    @Override
    public long getContentTime(String urlPath)
    {
        return m_content.getEntry(urlPath).flatMap(entry -> Optional.of(entry.getLastModified())).orElse(-1L);
    }
}
