/*
 *  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
 *
 *      https://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.tools.ant;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;

import org.apache.tools.ant.helper.ProjectHelper2;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.util.LoaderUtils;
import org.apache.tools.ant.util.StreamUtils;

/**
 * Repository of {@link ProjectHelper} found in the classpath or via
 * some System properties.
 *
 * <p>See the ProjectHelper documentation in the manual.</p>
 *
 * @since Ant 1.8.0
 */
public class ProjectHelperRepository {

    private static final String DEBUG_PROJECT_HELPER_REPOSITORY =
        "ant.project-helper-repo.debug";

    // The message log level is not accessible here because everything
    // is instantiated statically
    private static final boolean DEBUG =
        "true".equals(System.getProperty(DEBUG_PROJECT_HELPER_REPOSITORY));

    private static ProjectHelperRepository instance =
        new ProjectHelperRepository();

    private List<Constructor<? extends ProjectHelper>> helpers = new ArrayList<>();

    private static Constructor<ProjectHelper2> PROJECTHELPER2_CONSTRUCTOR;

    static {
        try {
            PROJECTHELPER2_CONSTRUCTOR = ProjectHelper2.class.getConstructor();
        } catch (Exception e) {
            // ProjectHelper2 must be available
            throw new BuildException(e);
        }
    }

    public static ProjectHelperRepository getInstance() {
        return instance;
    }

    private ProjectHelperRepository() {
        collectProjectHelpers();
    }

    private void collectProjectHelpers() {
        // First, try the system property
        registerProjectHelper(getProjectHelperBySystemProperty());

        // A JDK1.3 'service' (like in JAXP). That will plug a helper
        // automatically if in CLASSPATH, with the right META-INF/services.
        try {
            ClassLoader classLoader = LoaderUtils.getContextClassLoader();
            if (classLoader != null) {
                for (URL resource : Collections.list(classLoader.getResources(ProjectHelper.SERVICE_ID))) {
                    URLConnection conn = resource.openConnection();
                    conn.setUseCaches(false);
                    registerProjectHelper(getProjectHelperByService(conn.getInputStream()));
                }
            }

            InputStream systemResource =
                ClassLoader.getSystemResourceAsStream(ProjectHelper.SERVICE_ID);
            if (systemResource != null) {
                registerProjectHelper(getProjectHelperByService(systemResource));
            }
        } catch (Exception e) {
            System.err.println("Unable to load ProjectHelper from service "
                               + ProjectHelper.SERVICE_ID + " ("
                               + e.getClass().getName()
                               + ": " + e.getMessage() + ")");
            if (DEBUG) {
                e.printStackTrace(System.err); //NOSONAR
            }
        }
    }

    /**
     * Register the specified project helper into the repository.
     * <p>
     * The helper will be added after all the already registered helpers, but
     * before the default one (ProjectHelper2)
     *
     * @param helperClassName
     *            the fully qualified name of the helper
     * @throws BuildException
     *             if the class cannot be loaded or if there is no constructor
     *             with no argument
     * @since Ant 1.8.2
     */
    public void registerProjectHelper(String helperClassName)
            throws BuildException {
        registerProjectHelper(getHelperConstructor(helperClassName));
    }

    /**
     * Register the specified project helper into the repository.
     * <p>
     * The helper will be added after all the already registered helpers, but
     * before the default one (ProjectHelper2)
     *
     * @param helperClass
     *            the class of the helper
     * @throws BuildException
     *             if there is no constructor with no argument
     * @since Ant 1.8.2
     */
    public void registerProjectHelper(Class<? extends ProjectHelper> helperClass) throws BuildException {
        try {
            registerProjectHelper(helperClass.getConstructor());
        } catch (NoSuchMethodException e) {
            throw new BuildException("Couldn't find no-arg constructor in "
                    + helperClass.getName());
        }
    }

    private void registerProjectHelper(Constructor<? extends ProjectHelper> helperConstructor) {
        if (helperConstructor == null) {
            return;
        }
        if (DEBUG) {
            System.out.println("ProjectHelper "
                    + helperConstructor.getClass().getName() + " registered.");
        }
        helpers.add(helperConstructor);
    }

    private Constructor<? extends ProjectHelper> getProjectHelperBySystemProperty() {
        String helperClass = System.getProperty(ProjectHelper.HELPER_PROPERTY);
        try {
            if (helperClass != null) {
                return getHelperConstructor(helperClass);
            }
        } catch (SecurityException e) {
            System.err.println("Unable to load ProjectHelper class \""
                               + helperClass + " specified in system property "
                               + ProjectHelper.HELPER_PROPERTY + " ("
                               + e.getMessage() + ")");
            if (DEBUG) {
                e.printStackTrace(System.err); //NOSONAR
            }
        }
        return null;
    }

    private Constructor<? extends ProjectHelper> getProjectHelperByService(InputStream is) {
        try {
            // This code is needed by EBCDIC and other strange systems.
            // It's a fix for bugs reported in xerces
            BufferedReader rd = new BufferedReader(new InputStreamReader(is,
                    StandardCharsets.UTF_8));
            String helperClassName = rd.readLine();
            rd.close();

            if (helperClassName != null && !helperClassName.isEmpty()) {
                return getHelperConstructor(helperClassName);
            }
        } catch (Exception e) {
            System.out.println("Unable to load ProjectHelper from service "
                    + ProjectHelper.SERVICE_ID + " (" + e.getMessage() + ")");
            if (DEBUG) {
                e.printStackTrace(System.err); //NOSONAR
            }
        }
        return null;
    }

    /**
     * Get the constructor with not argument of an helper from its class name.
     * It'll first try the thread class loader, then Class.forName() will load
     * from the same loader that loaded this class.
     *
     * @param helperClass
     *            The name of the class to create an instance of. Must not be
     *            <code>null</code>.
     *
     * @return the constructor of the specified class.
     *
     * @exception BuildException
     *                if the class cannot be found or if a constructor with no
     *                argument cannot be found.
     */
    private Constructor<? extends ProjectHelper> getHelperConstructor(String helperClass) throws BuildException {
        ClassLoader classLoader = LoaderUtils.getContextClassLoader();
        try {
            Class<?> clazz = null;
            if (classLoader != null) {
                try {
                    clazz = classLoader.loadClass(helperClass);
                } catch (ClassNotFoundException ex) {
                    // try next method
                }
            }
            if (clazz == null) {
                clazz = Class.forName(helperClass);
            }
            return clazz.asSubclass(ProjectHelper.class).getConstructor();
        } catch (Exception e) {
            throw new BuildException(e);
        }
    }

    /**
     * Get the helper that will be able to parse the specified build file. The helper
     * will be chosen among the ones found in the classpath
     *
     * @param buildFile Resource
     * @return the first ProjectHelper that fit the requirement (never <code>null</code>).
     */
    public ProjectHelper getProjectHelperForBuildFile(Resource buildFile) throws BuildException {
        ProjectHelper ph = StreamUtils.iteratorAsStream(getHelpers())
                .filter(helper -> helper.canParseBuildFile(buildFile))
                .findFirst().orElse(null);

        if (ph == null) {
            throw new BuildException("BUG: at least the ProjectHelper2 should "
                    + "have supported the file " + buildFile);
        }
        if (DEBUG) {
            System.out.println("ProjectHelper " + ph.getClass().getName()
                    + " selected for the build file " + buildFile);
        }
        return ph;
    }

    /**
     * Get the helper that will be able to parse the specified antlib. The helper
     * will be chosen among the ones found in the classpath
     *
     * @param antlib Resource
     * @return the first ProjectHelper that fit the requirement (never <code>null</code>).
     */
    public ProjectHelper getProjectHelperForAntlib(Resource antlib) throws BuildException {
        ProjectHelper ph = StreamUtils.iteratorAsStream(getHelpers())
                .filter(helper -> helper.canParseAntlibDescriptor(antlib))
                .findFirst().orElse(null);

        if (ph == null) {
            throw new BuildException("BUG: at least the ProjectHelper2 should "
                    + "have supported the file " + antlib);
        }
        if (DEBUG) {
            System.out.println("ProjectHelper " + ph.getClass().getName()
                    + " selected for the antlib " + antlib);
        }
        return ph;
    }

    /**
     * Get an iterator on the list of project helpers configured. The iterator
     * will always return at least one element as there will always be the
     * default project helper configured.
     *
     * @return an iterator of {@link ProjectHelper}
     */
    public Iterator<ProjectHelper> getHelpers() {
        Stream.Builder<Constructor<? extends ProjectHelper>> b = Stream.builder();
        helpers.forEach(b::add);
        return b.add(PROJECTHELPER2_CONSTRUCTOR).build().map(c -> {
            try {
                return c.newInstance();
            } catch (Exception e) {
                throw new BuildException("Failed to invoke no-arg constructor"
                        + " on " + c.getName());
            }
        }).map(ProjectHelper.class::cast).iterator();
    }
}
