/*=============================================================================#
 # 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.IOException;
import java.io.InputStream;
import java.io.OutputStream;
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.CollectionUtils;
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 {
		try {
			final List<BundleEntry> bundles= resolveBundles(ImCollections.newList(ServerUtils.RJ_SERVER_SPEC));
			for (final BundleEntry bundle : bundles) {
				if (bundle instanceof BundleEntry.Dir) {
					final Path policyPath= bundle.getResourcePath(LOCALHOST_POLICY_FILENAME);
					if (policyPath != null && Files.isRegularFile(policyPath)) {
						return policyPath.toUri().toString();
					}
				}
			}
			for (final BundleEntry bundle : bundles) {
				final String s= bundle.getResourceUrlString(LOCALHOST_POLICY_FILENAME);
				if (s != null) {
					return s;
				}
			}
			throw new UnsupportedOperationException("bundleEntries=" + ((!bundles.isEmpty()) ? //$NON-NLS-1$
					"n\t" + CollectionUtils.toString(bundles, "\n\t") : //$NON-NLS-1$
					"<none>" )); //$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 var file= Path.of(path);
		if (Files.notExists(file)) {
			return null;
		}
		return Files.newInputStream(file);
	}
	
	protected OutputStream getOutputStream(final String path) throws IOException {
		final var file= Path.of(path);
		return Files.newOutputStream(file);
	}
	
	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) {}
			}
		}
	}
	
}
