/*=============================================================================#
 # Copyright (c) 2010, 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.internal.rhelp.core;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;

import org.eclipse.statet.internal.rhelp.core.index.REnvIndexReader;
import org.eclipse.statet.internal.rhelp.core.server.ServerClientSupport;
import org.eclipse.statet.rhelp.core.DocResource;
import org.eclipse.statet.rhelp.core.REnvHelp;
import org.eclipse.statet.rhelp.core.REnvHelpConfiguration;
import org.eclipse.statet.rhelp.core.RHelpCore;
import org.eclipse.statet.rhelp.core.RHelpKeywordGroup;
import org.eclipse.statet.rhelp.core.RHelpPage;
import org.eclipse.statet.rhelp.core.RHelpSearchQuery;
import org.eclipse.statet.rhelp.core.RHelpSearchRequestor;
import org.eclipse.statet.rhelp.core.RPkgHelp;
import org.eclipse.statet.rj.renv.core.REnv;
import org.eclipse.statet.rj.renv.core.REnvConfiguration;


@NonNullByDefault
public final class REnvHelpImpl implements REnvHelp {
	
	
	public static final long NOT_AVAILABLE_STAMP= 0;
	
	public static long createStamp() {
		long stamp= System.currentTimeMillis();
		if (stamp == NOT_AVAILABLE_STAMP) {
			stamp++;
		}
		return stamp;
	}
	
	
	private final REnv rEnv;
	
	private final long stamp;
	
	private final @Nullable String docDir;
	private final ImList<DocResource> manuals;
	private final ImList<DocResource> miscRes;
	
	private final ImList<RHelpKeywordGroup> keywords;
	
	private final ImList<RPkgHelp> packages;
	private @Nullable volatile Map<String, RPkgHelp> packageMap;
	private @Nullable volatile REnvHelpIndex index;
	
	private boolean disposed;
	
	private final ReentrantReadWriteLock lock= new ReentrantReadWriteLock();
	
	
	public REnvHelpImpl(final REnv rEnv, final long stamp,
			final @Nullable String docDir, final ImList<DocResource> manuals, final ImList<DocResource> miscRes,
			final ImList<RHelpKeywordGroup> keywords, final ImList<RPkgHelp> packages) {
		this.rEnv= rEnv;
		this.stamp= stamp;
		this.docDir= docDir;
		this.manuals= manuals;
		this.miscRes= miscRes;
		this.keywords= keywords;
		this.packages= packages;
	}
	
	
	public void dispose() {
		this.lock.writeLock().lock();
		try {
			this.disposed= true;
			this.packageMap= null;
			if (this.index != null) {
				this.index.dispose();
				this.index= null;
			}
		}
		finally {
			this.lock.writeLock().unlock();
		}
	}
	
	@Override
	public REnv getREnv() {
		return this.rEnv;
	}
	
	public long getStamp() {
		return this.stamp;
	}
	
	
	public @Nullable String getDocDir() {
		return this.docDir;
	}
	
	
	public void lock() {
		this.lock.readLock().lock();
	}
	
	@Override
	public void unlock() {
		this.lock.readLock().unlock();
	}
	
	
	@Override
	public ImList<DocResource> getManuals() {
		return this.manuals;
	}
	
	@Override
	public ImList<DocResource> getMiscResources() {
		return this.miscRes;
	}
	
	@Override
	public ImList<RHelpKeywordGroup> getKeywords() {
		return this.keywords;
	}
	
	@Override
	public ImList<RPkgHelp> getPkgs() {
		return this.packages;
	}
	
	@Override
	public @Nullable RPkgHelp getPkgHelp(final String pkgName) {
		return getPackageMap().get(pkgName);
	}
	
	private Map<String, RPkgHelp> getPackageMap() {
		Map<String, RPkgHelp> map= this.packageMap;
		if (map == null) {
			synchronized (this) {
				if (this.disposed) {
					throw new IllegalStateException("This help index is no longer valid.");
				}
				
				map= this.packageMap;
				if (map == null) {
					map= new HashMap<>(this.packages.size());
					for (final RPkgHelp pkgHelp : this.packages) {
						map.put(pkgHelp.getName(), pkgHelp);
					}
					this.packageMap= map;
				}
			}
		}
		return map;
	}
	
	synchronized void setIndex(final REnvHelpIndex index) {
		if (!this.disposed && this.index == null) {
			this.index= index;
		}
	}
	
	private REnvHelpIndex getIndex() {
		REnvHelpIndex index= this.index;
		if (index == null) {
			synchronized (this) {
				if (this.disposed) {
					throw new IllegalStateException("This help index is no longer valid.");
				}
				
				index= this.index;
				if (index == null) {
					final REnvHelpConfiguration rEnvConfig= this.rEnv.get(REnvHelpConfiguration.class);
					if (rEnvConfig == null) {
						throw new IllegalStateException("This R environment is no longer valid.");
					}
					try {
						switch (rEnvConfig.getStateSharedType()) {
						case REnvConfiguration.SHARED_DIRECTORY:
							index= new REnvIndexReader(rEnvConfig);
							break;
						case REnvConfiguration.SHARED_SERVER:
							index= ServerClientSupport.getInstance().getREnvHelpAccess(rEnvConfig);
							break;
						default:
							throw new UnsupportedOperationException(rEnvConfig.getStateSharedType());
						}
					}
					catch (final Exception e) {
						RHelpCoreInternals.log(new ErrorStatus(RHelpCore.BUNDLE_ID,
								"An error occurred when initializing searcher for the R help index.",
								e ));
						throw new RuntimeException("An error occurred when reading R help index.");
					}
					this.index= index;
				}
			}
		}
		return index;
	}
	
	@Override
	public @Nullable RHelpPage getPage(final String pkgName, final String name) {
		final RPkgHelp pkgHelp= getPackageMap().get(pkgName);
		if (pkgHelp != null) {
			return pkgHelp.getPage(name);
		}
		return null;
	}
	
	@Override
	public List<RHelpPage> getPagesForTopic(final String topic,
			final @Nullable ProgressMonitor m) throws StatusException {
		return getIndex().getPagesForTopic(topic, getPackageMap(),
				10, m );
	}
	
	
	public @Nullable String getHtmlPage(final RPkgHelp pkgHelp, final String pageName,
			final @Nullable String queryString) throws StatusException {
		return getIndex().getHtmlPage(pkgHelp, pageName, queryString,
				-1, null );
	}
	
	
	public void search(final RHelpSearchQuery query,
			final RHelpSearchRequestor requestor) throws StatusException {
		getIndex().search(query, this.packages, getPackageMap(), requestor);
	}
	
}
