/*=============================================================================#
 # Copyright (c) 2013, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rj.server.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Properties;
import java.util.regex.Pattern;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.runtime.CommonsRuntime;
import org.eclipse.statet.jcommons.runtime.bundle.BundleEntry;
import org.eclipse.statet.jcommons.runtime.bundle.BundleSpec;
import org.eclipse.statet.jcommons.status.StatusException;

import org.eclipse.statet.rj.RjInvalidConfigurationException;


/**
 * Helps to setup a server.
 * 
 * <h4>System properties:</h4>
 * <table>
 *   <tr>
 *     <th>Name</th>
 *     <th>Description</th>
 *     <th>Default</th>
 *   </tr>
 *   <tr>
 *     <td><code>org.eclipse.statet.rj.context.BundleResolvers<code></td>
 *     <td>Comma separated list of resolvers which will be used to resolve library bundles in the
 *         specified order.<br/>
 *         Possible value: default, RefClass</td>
 *     <td>default</td>
 *   </tr>
 * <table>
 */
@NonNullByDefault
public class RJContext {
	
	
	public static final String RJ_SERVER_CLASS_PATH_PROPERTY_KEY= "org.eclipse.statet.rj.server.ClassPath.urls"; //$NON-NLS-1$
	
	public static final String RJ_PATH_SEPARATOR= ":,:"; //$NON-NLS-1$
	private static final Pattern RJ_PATH_SEPARATOR_PATTERN= Pattern.compile(RJ_PATH_SEPARATOR, Pattern.LITERAL);
	
	protected static final String LOCALHOST_POLICY_FILENAME= "localhost.policy"; //$NON-NLS-1$
	
	
	public RJContext() {
	}
	
	
	public List<BundleEntry> resolveBundles(final List<BundleSpec> bundleSpecs)
			throws StatusException {
		return CommonsRuntime.getEnvironment().resolveBundles(bundleSpecs);
	}
	
	public String getServerPolicyFilePath() throws RjInvalidConfigurationException {
		final URL resource= RJContext.class.getClassLoader().getResource(LOCALHOST_POLICY_FILENAME);
		if (resource != null) {
			resource.toString();
		}
		try {
			final BundleEntry lib= resolveBundles(ImCollections.newList(ServerUtils.RJ_SERVER_SPEC)).get(0);
			final Path policyPath= lib.getResourcePath(LOCALHOST_POLICY_FILENAME);
			if (policyPath != null && Files.isRegularFile(policyPath)) {
				return policyPath.toUri().toString();
			}
			else {
				final String s= lib.getResourceUrlString(LOCALHOST_POLICY_FILENAME);
				if (s != null) {
					return s;
				}
			}
			throw new UnsupportedOperationException(String.format("BundleEntry= '%1$s'", lib)); //$NON-NLS-1$
		}
		catch (final Exception e) {
			throw new RjInvalidConfigurationException("Failed find server policy file.", e);
		}
	}
	
	
	protected String getPropertiesDirPath() {
		return System.getProperty("user.dir"); //$NON-NLS-1$
	}
	
	protected @Nullable InputStream getInputStream(final String path) throws IOException {
		final File file= new File(path);
		if (!file.exists()) {
			return null;
		}
		return new FileInputStream(file);
	}
	
	protected OutputStream getOutputStream(final String path) throws IOException {
		final File file= new File(path);
		return new FileOutputStream(file, false);
	}
	
	public @Nullable Properties loadProperties(final String name) throws IOException {
		if (name == null) {
			throw new NullPointerException("name"); //$NON-NLS-1$
		}
		final String path= getPropertiesDirPath() + '/' + name + ".properties"; //$NON-NLS-1$
		final InputStream in= getInputStream(path);
		if (in == null) {
			return null;
		}
		
		final Properties properties= new Properties();
		try {
			properties.load(in);
		}
		finally {
			if (in != null) {
				try {
					in.close();
				}
				catch (final IOException e) {}
			}
		}
		
		return properties;
	}
	
	public void saveProperties(final String name, final Properties properties) throws IOException {
		if (name == null) {
			throw new NullPointerException("name"); //$NON-NLS-1$
		}
		if (properties == null) {
			throw new NullPointerException("properties"); //$NON-NLS-1$
		}
		final String path= getPropertiesDirPath() + '/' + name + ".properties"; //$NON-NLS-1$
		final OutputStream out= getOutputStream(path);
		
		try {
			properties.store(out, null);
		}
		finally {
			if (out != null) {
				try {
					out.close();
				}
				catch (final IOException e) {}
			}
		}
	}
	
}
