/*
 * 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.openjpa.lib.meta;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.NoSuchElementException;

import org.apache.openjpa.lib.util.ClassUtil;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.MultiClassLoader;

/**
 * Iterator over all metadata resources that might contain the
 * metadata for a given class, starting with the most general. Assumes that
 * package-level resources are named "package.&lt;suffix&gt;".
 *
 * @author Abe White
 */
public class ClassMetaDataIterator implements MetaDataIterator {

    private final ClassLoader _loader;
    private final List<String> _locs;
    private int _loc = -1;
    private final List<URL> _urls = new ArrayList<>(3);
    private int _url = -1;

    /**
     * Constructor; supply the class whose metadata to find, the suffix
     * of metadata files, and whether to parse top-down or bottom-up.
     */
    public ClassMetaDataIterator(Class<?> cls, String suffix, boolean topDown) {
        this(cls, suffix, null, topDown);
    }

    /**
     * Constructor; supply the class whose metadata to find, the suffix
     * of metadata files, and whether to parse top-down or bottom-up.
     */
    public ClassMetaDataIterator(Class<?> cls, String suffix,
            ClassLoader loader, boolean topDown) {
        // skip classes that can't have metadata
        if (cls != null && (cls.isPrimitive()
            || cls.getName().startsWith("java.")
            || cls.getName().startsWith("javax."))) {
            _loader = null;
            _locs = Collections.emptyList();
            return;
        }

        if (loader == null) {
            MultiClassLoader multi = AccessController
                .doPrivileged(J2DoPrivHelper.newMultiClassLoaderAction());
            multi.addClassLoader(MultiClassLoader.SYSTEM_LOADER);
            multi.addClassLoader(MultiClassLoader.THREAD_LOADER);
            multi.addClassLoader(getClass().getClassLoader());
            if (cls != null)
            {
                ClassLoader clsLoader = (ClassLoader)
                    AccessController.doPrivileged(
                        J2DoPrivHelper.getClassLoaderAction(cls));
                if (clsLoader != null)
                    multi.addClassLoader(clsLoader);
            }
            loader = multi;
        }
        _loader = loader;

        // collect the set of all possible metadata locations; start with
        // system locations
        _locs = new ArrayList<>();
        _locs.add("META-INF/package" + suffix);
        _locs.add("WEB-INF/package" + suffix);
        _locs.add("package" + suffix);

        // put this legacy location at the end regardless of whether we're
        // going top down or bottom up so we don't have to parse it as often
        // during testing
        if (!topDown)
            _locs.add("system" + suffix);

        if (cls != null) {
            // also check:
            // 1. for each package from the top down to cls' package:
            // <path>/package<suffix>
            // <path>/<package-name><suffix> (legacy support)
            // <path>/../<package-name><suffix> (legacy support)
            // 2. <path>/<class-name><suffix>
            String pkg = ClassUtil.getPackageName(cls).replace('.', '/');
            if (pkg.length() > 0) {
                int idx, start = 0;
                String pkgName, path, upPath = "";
                do {
                    idx = pkg.indexOf('/', start);
                    if (idx == -1) {
                        pkgName = (start == 0) ? pkg : pkg.substring(start);
                        path = pkg + "/";
                    } else {
                        pkgName = pkg.substring(start, idx);
                        path = pkg.substring(0, idx + 1);
                    }

                    _locs.add(path + "package" + suffix);
                    _locs.add(path + pkgName + suffix); // legacy
                    _locs.add(upPath + pkgName + suffix); // legacy
                    if (idx == -1)
                        _locs.add(path + ClassUtil.getClassName(cls) + suffix);

                    start = idx + 1;
                    upPath = path;
                }
                while (idx != -1);
            } else {
                // <class-name><suffix> for top-level classes
                _locs.add(cls.getName() + suffix);
            }
        }
        if (topDown)
            _locs.add("system" + suffix); // legacy
        else
            Collections.reverse(_locs);
    }

    @Override
    public boolean hasNext() throws IOException {
        Enumeration<URL> e;
        while (_url + 1 >= _urls.size()) {
            if (++_loc >= _locs.size())
                return false;

            _url = -1;
            _urls.clear();
            try {
                e = AccessController.doPrivileged(
                    J2DoPrivHelper.getResourcesAction(
                        _loader, _locs.get(_loc)));
            } catch (PrivilegedActionException pae) {
                throw (IOException) pae.getException();
            }
            while (e.hasMoreElements())
                _urls.add(e.nextElement());
        }
        return true;
    }

    @Override
    public URL next() throws IOException {
        if (!hasNext())
            throw new NoSuchElementException();
        return _urls.get(++_url);
    }

    @Override
    public InputStream getInputStream() throws IOException {
        if (_url == -1 || _url >= _urls.size())
            throw new IllegalStateException();
        try {
            return AccessController.doPrivileged(
                J2DoPrivHelper.openStreamAction(_urls.get(_url)));
        } catch (PrivilegedActionException pae) {
            throw (IOException) pae.getException();
        }
    }

    @Override
    public File getFile() throws IOException {
        if (_url == -1 || _url >= _urls.size())
            throw new IllegalStateException();
        File file = new File(URLDecoder.decode((_urls.get(_url)).getFile()));
        return ((AccessController.doPrivileged(
            J2DoPrivHelper.existsAction(file))).booleanValue()) ? file:null;
    }

    @Override
    public void close() {
    }
}
