package org.apache.commons.jcs3.auxiliary.remote;

/*
 * 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.
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RMISocketFactory;
import java.util.Properties;

import org.apache.commons.jcs3.log.Log;
import org.apache.commons.jcs3.log.LogManager;

/**
 * This class provides some basic utilities for doing things such as starting
 * the registry properly.
 */
public class RemoteUtils
{
    /** The logger. */
    private static final Log log = LogManager.getLog(RemoteUtils.class);

    /** No instances please. */
    private RemoteUtils()
    {
        super();
    }

    /**
     * Creates and exports a registry on the specified port of the local host.
     * <p>
     *
     * @param port
     * @return the registry
     */
    public static Registry createRegistry(int port)
    {
        Registry registry = null;

        // if ( log.isInfoEnabled() )
        // {
        // log.info( "createRegistry> Setting security manager" );
        // }
        //
        // System.setSecurityManager( new RMISecurityManager() );

        if (port < 1024)
        {
            log.warn("createRegistry> Port chosen was less than 1024, will use default [{0}] instead.",
                    Registry.REGISTRY_PORT);
            port = Registry.REGISTRY_PORT;
        }

        try
        {
            registry = LocateRegistry.createRegistry(port);
            log.info("createRegistry> Created the registry on port {0}", port);
        }
        catch (RemoteException e)
        {
            log.warn("createRegistry> Problem creating registry. It may already be started.",
                    e);
        }
        catch (Throwable t)
        {
            log.error("createRegistry> Problem creating registry.", t);
        }

        if (registry == null)
        {
            try
            {
                registry = LocateRegistry.getRegistry(port);
            }
            catch (RemoteException e)
            {
                log.error("createRegistry> Problem getting a registry reference.", e);
            }
        }

        return registry;
    }

    /**
     * Loads properties for the named props file.
     * First tries class path, then file, then URL
     * <p>
     *
     * @param propFile
     * @return The properties object for the file
     * @throws IOException
     */
    public static Properties loadProps(String propFile)
            throws IOException
    {
        InputStream is = RemoteUtils.class.getResourceAsStream(propFile);

        if (null == is) // not found in class path
        {
            // Try root of class path
            if (propFile != null && !propFile.startsWith("/"))
            {
                is = RemoteUtils.class.getResourceAsStream("/" + propFile);
            }
        }

        if (null == is) // not found in class path
        {
            if (new File(propFile).exists())
            {
                // file found
                is = new FileInputStream(propFile);
            }
            else
            {
                // try URL
                is = new URL(propFile).openStream();
            }
        }

        Properties props = new Properties();
        try
        {
            props.load(is);
            log.debug("props.size={0}", () -> props.size());

            if (log.isTraceEnabled())
            {
                StringBuilder buf = new StringBuilder();
                props.forEach((key, value)
                        -> buf.append('\n').append(key).append(" = ").append(value));
                log.trace(buf.toString());
            }

        }
        catch (IOException ex)
        {
            log.error("Error loading remote properties, for file name "
                    + "[{0}]", propFile, ex);
        }
        finally
        {
            if (is != null)
            {
                is.close();
            }
        }
        return props;
    }

    /**
     * Configure a custom socket factory to set the timeout value. This sets the
     * global socket factory. It's used only if a custom factory is not
     * configured for the specific object.
     * <p>
     *
     * @param timeoutMillis
     */
    public static void configureGlobalCustomSocketFactory(final int timeoutMillis)
    {
        try
        {
            // Don't set a socket factory if the setting is -1
            if (timeoutMillis > 0)
            {
                log.info("RmiSocketFactoryTimeoutMillis [{0}]. "
                    + " Configuring a custom socket factory.", timeoutMillis);

                // use this socket factory to add a timeout.
                RMISocketFactory.setSocketFactory(new RMISocketFactory()
                {
                    @Override
                    public Socket createSocket(String host, int port)
                            throws IOException
                    {
                        Socket socket = new Socket();
                        socket.setSoTimeout(timeoutMillis);
                        socket.setSoLinger(false, 0);
                        socket.connect(new InetSocketAddress(host, port), timeoutMillis);
                        return socket;
                    }

                    @Override
                    public ServerSocket createServerSocket(int port)
                            throws IOException
                    {
                        return new ServerSocket(port);
                    }
                });
            }
        }
        catch (IOException e)
        {
            // Only try to do it once. Otherwise we
            // Generate errors for each region on construction.
            RMISocketFactory factoryInUse = RMISocketFactory.getSocketFactory();
            if (factoryInUse != null && !factoryInUse.getClass().getName().startsWith("org.apache.commons.jcs3"))
            {
                log.info("Could not create new custom socket factory. {0} Factory in use = {1}",
                        () -> e.getMessage(), () -> RMISocketFactory.getSocketFactory());
            }
        }
    }

    /**
     * Get the naming url used for RMI registration
     *
     * @param location
     *            the remote location
     * @param serviceName
     *            the remote service name
     * @return the URL for RMI lookup
     */
    public static String getNamingURL(final RemoteLocation location, final String serviceName)
    {
        return getNamingURL(location.getHost(), location.getPort(), serviceName);
    }

    /**
     * Get the naming url used for RMI registration
     *
     * @param registryHost
     *            the remote host
     * @param registryPort
     *            the remote port
     * @param serviceName
     *            the remote service name
     * @return the URL for RMI lookup
     */
    public static String getNamingURL(final String registryHost, final int registryPort, final String serviceName)
    {
        if (registryHost.contains(":"))
        { // TODO improve this check? See also JCS-133
            return "//[" + registryHost.replaceFirst("%", "%25") + "]:" + registryPort + "/" + serviceName;
        }
        final String registryURL = "//" + registryHost + ":" + registryPort + "/" + serviceName;
        return registryURL;
    }
}
