/*
 * 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.webbeans.arquillian.standalone;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.webbeans.spi.BDABeansXmlScanner;
import org.apache.webbeans.spi.ScannerService;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ArchivePath;
import org.jboss.shrinkwrap.api.Filters;
import org.jboss.shrinkwrap.api.Node;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.ArchiveAsset;
import org.jboss.shrinkwrap.api.asset.Asset;
import org.jboss.shrinkwrap.api.asset.FileAsset;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;

/**
 *
 */
public class OwbArquillianScannerService implements ScannerService
{

    private final static String WEB_INF_CLASS_FOLDER = "/WEB-INF/classes/";

    private boolean beansXmlBdaScanningEnabled;
    private Archive archive;

    private UrlSet beansXmls = new UrlSet();
    private Set<Class<?>> beanClasses = new HashSet<Class<?>>();


    public OwbArquillianScannerService()
    {
        this.beansXmlBdaScanningEnabled = false;
    }

    @Override
    public BDABeansXmlScanner getBDABeansXmlScanner()
    {
        return null;
    }

    @Override
    public void init(Object object)
    {
        // nothing to do
    }

    public void setArchive(Archive archive)
    {
        this.archive = archive;
    }

    @Override
    public void scan()
    {
        if (archive == null)
        {
            return;
        }

        final String archiveName = archive.getName();
        if (archiveName.endsWith(".jar"))
        {
            scanJarArchive(archive);
        }
        else if (archiveName.endsWith(".war"))
        {
            scanWebArchive(archive);
        }
        else
        {
            throw new IllegalStateException("Scanning of Archive " + archive.getClass().getName() + "Not yet implemented");
        }
    }

    @Override
    public Set<URL> getBeanXmls()
    {
        return beansXmls;
    }

    @Override
    public Set<Class<?>> getBeanClasses()
    {
        return beanClasses;
    }

    @Override
    public void release()
    {
        beansXmls.clear();
        beanClasses.clear();
    }

    @Override
    public boolean isBDABeansXmlScanningEnabled()
    {
        return beansXmlBdaScanningEnabled;
    }

    // --------- private implementation -----------

    private void scanWebArchive(final Archive<?> archive)
    {
        URL webBeansXmlUrl = getBeanXmlUrl(archive, "WEB-INF/beans.xml");
        if (webBeansXmlUrl != null)
        {
            beansXmls.add(webBeansXmlUrl);
        }

        URL metainfBeansXmlUrl = getBeanXmlUrl(archive, WEB_INF_CLASS_FOLDER + "META-INF/beans.xml");
        if (metainfBeansXmlUrl != null)
        {
            beansXmls.add(metainfBeansXmlUrl);
        }

        if (metainfBeansXmlUrl != null || webBeansXmlUrl != null)
        {
            // in this case we need to scan the WEB-INF/classses folder for .class files
            Map<ArchivePath, Node> classes = archive.getContent(Filters.include(WEB_INF_CLASS_FOLDER + ".*\\.class"));
            scanClasses(classes, WEB_INF_CLASS_FOLDER);
        }


        // and now scan all the jars in the WAR
        Map<ArchivePath, Node> jars = archive.getContent(Filters.include("/WEB-INF/lib/.*\\.jar"));
        for (Map.Entry<ArchivePath, Node> jarEntry : jars.entrySet())
        {
            Asset asset = jarEntry.getValue().getAsset();
            if (asset instanceof FileAsset)
            {
                FileAsset fileAsset = (FileAsset) asset;
                if (fileAsset.getSource().getName().endsWith(".jar"))
                {
                    Archive<?> fileArchive = ShrinkWrap.createFromZipFile(JavaArchive.class, fileAsset.getSource());
                    asset = new ArchiveAsset(fileArchive, ZipExporter.class);
                }
            }
            if (asset instanceof ArchiveAsset)
            {
                ArchiveAsset archiveAsset = (ArchiveAsset) asset;
                JavaArchive jarArchive = (JavaArchive) archiveAsset.getArchive();
                scanJarArchive(jarArchive);
            }
        }

    }

    private void scanJarArchive(final Archive<?> archive)
    {
        URL beansXmlUrl = getBeanXmlUrl(archive, "META-INF/beans.xml");

        if (beansXmlUrl == null)
        {
            // this is not a CDI archive
            return;
        }

        // otherwise we store it for later use
        beansXmls.add(beansXmlUrl);

        // and now add all classes
        Map<ArchivePath, Node> classes = archive.getContent(Filters.include(".*\\.class"));
        scanClasses(classes, null);
    }

    /**
     *
     * @param classes the scanned classes
     * @param classBasePath the base class in which the classes are, or null if they are directly in the root
     */
    private void scanClasses(Map<ArchivePath, Node> classes, String classBasePath)
    {
        for (Map.Entry<ArchivePath, Node> classEntry : classes.entrySet())
        {
            String className = classEntry.getKey().get();

            if (classBasePath != null && className.startsWith(WEB_INF_CLASS_FOLDER))
            {
                className = className.substring(WEB_INF_CLASS_FOLDER.length());
            }

            // cut off leading slashes
            if (className.startsWith("/"))
            {
                className = className.substring(1);
            }

            // cut off ".class"
            className = className.substring(0, className.length() - ".class".length());

            className = className.replace('/', '.');


            try
            {
                Class<?> beanClass = Class.forName(className);
                beanClasses.add(beanClass);
            }
            catch (ClassNotFoundException cnfe)
            {
                throw new RuntimeException("Could not scan class", cnfe);
            }
        }
    }

    private URL getBeanXmlUrl(Archive archive, String beansXmlPath)
    {
        final Node beansXml = archive.get(beansXmlPath);

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

        try
        {
            String urlLocation = "archive://" + archive.getName() + "/" + beansXmlPath;

            return  new URL(null, urlLocation, new URLStreamHandler()
                        {
                            @Override
                            protected URLConnection openConnection(URL u) throws IOException
                            {
                                return new URLConnection(u)
                                {
                                    @Override
                                    public void connect() throws IOException
                                    {}

                                    @Override
                                    public InputStream getInputStream() throws IOException
                                    {
                                        return beansXml.getAsset().openStream();
                                    }
                                };
                            };
                        });
        }
        catch (Exception e)
        {
            RuntimeException runtimeException;
            if (e instanceof RuntimeException)
            {
                runtimeException = (RuntimeException) e;
            }
            else
            {
                runtimeException = new RuntimeException("Error while parsing beans.xml location", e);
            }

            throw runtimeException;
        }
    }


    public void clear()
    {
        archive = null;

        beansXmls = new UrlSet();
        beanClasses = new HashSet<Class<?>>();
    }
}
