/*
 *  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.tomcat.jni;

import java.io.File;

/**
 * Manages loading of the Tomcat Native (tcnative) library.
 */
public final class Library {

    /* Default library names - use 2.x in preference to 1.x if both are available */
    private static final String[] NAMES = { "tcnative-2", "libtcnative-2", "tcnative-1", "libtcnative-1" };
    /* System property used to define CATALINA_HOME */
    private static final String CATALINA_HOME_PROP = "catalina.home";
    /*
     * A handle to the unique Library singleton instance.
     */
    private static Library _instance = null;

    private Library() throws Exception {
        boolean loaded = false;
        StringBuilder err = new StringBuilder();
        File binLib = new File(System.getProperty(CATALINA_HOME_PROP), "bin");
        for (int i = 0; i < NAMES.length; i++) {
            File library = new File(binLib, System.mapLibraryName(NAMES[i]));
            try {
                System.load(library.getAbsolutePath());
                loaded = true;
            } catch (VirtualMachineError t) {
                throw t;
            } catch (Throwable t) {
                if (library.exists()) {
                    // File exists but failed to load
                    throw t;
                }
                if (i > 0) {
                    err.append(", ");
                }
                err.append(t.getMessage());
            }
            if (loaded) {
                break;
            }
        }
        if (!loaded) {
            String path = System.getProperty("java.library.path");
            String[] paths = path.split(File.pathSeparator);
            for (String value : NAMES) {
                try {
                    System.loadLibrary(value);
                    loaded = true;
                } catch (VirtualMachineError t) {
                    throw t;
                } catch (Throwable t) {
                    String name = System.mapLibraryName(value);
                    for (String s : paths) {
                        File fd = new File(s, name);
                        if (fd.exists()) {
                            // File exists but failed to load
                            throw t;
                        }
                    }
                    if (!err.isEmpty()) {
                        err.append(", ");
                    }
                    err.append(t.getMessage());
                }
                if (loaded) {
                    break;
                }
            }
        }
        if (!loaded) {
            StringBuilder names = new StringBuilder();
            for (String name : NAMES) {
                names.append(name);
                names.append(", ");
            }
            throw new LibraryNotFoundError(names.substring(0, names.length() - 2), err.toString());
        }
    }

    private Library(String libraryName) {
        System.loadLibrary(libraryName);
    }

    /**
     * Create Tomcat Native's global APR pool. This has to be the first call to TCN library.
     */
    private static native boolean initialize();

    /**
     * Destroys Tomcat Native's global APR pool. This has to be the last call to TCN library. This will destroy any APR
     * root pools that have not been explicitly destroyed.
     */
    public static native void terminate();

    /* Internal function for loading APR Features */
    private static native int version(int what);

    /**
     * TCN major version.
     */
    public static int TCN_MAJOR_VERSION = 0;
    /**
     * TCN minor version.
     */
    public static int TCN_MINOR_VERSION = 0;
    /**
     * TCN patch version.
     */
    public static int TCN_PATCH_VERSION = 0;
    /**
     * TCN is development version flag.
     */
    public static int TCN_IS_DEV_VERSION = 0;
    /**
     * APR major version.
     */
    public static int APR_MAJOR_VERSION = 0;
    /**
     * APR minor version.
     */
    public static int APR_MINOR_VERSION = 0;
    /**
     * APR patch version.
     */
    public static int APR_PATCH_VERSION = 0;
    /**
     * APR is development version flag.
     */
    public static int APR_IS_DEV_VERSION = 0;

    /**
     * Returns the TCN version string.
     *
     * @return the TCN version string
     */
    public static native String versionString();

    /**
     * Returns the APR version string.
     *
     * @return the APR version string
     */
    public static native String aprVersionString();

    /**
     * Setup any APR internal data structures. This MUST be the first function called for any APR library.
     *
     * @param libraryName the name of the library to load
     *
     * @return {@code true} if the native code was initialized successfully otherwise {@code false}
     *
     * @throws Exception if a problem occurred during initialization
     */
    public static synchronized boolean initialize(String libraryName) throws Exception {
        if (_instance == null) {
            if (libraryName == null) {
                _instance = new Library();
            } else {
                _instance = new Library(libraryName);
            }
            TCN_MAJOR_VERSION = version(0x01);
            TCN_MINOR_VERSION = version(0x02);
            TCN_PATCH_VERSION = version(0x03);
            TCN_IS_DEV_VERSION = version(0x04);
            APR_MAJOR_VERSION = version(0x11);
            APR_MINOR_VERSION = version(0x12);
            APR_PATCH_VERSION = version(0x13);
            APR_IS_DEV_VERSION = version(0x14);

            if (APR_MAJOR_VERSION < 1) {
                throw new UnsatisfiedLinkError("Unsupported APR Version (" + aprVersionString() + ")");
            }
        }
        return initialize();
    }
}
