/*=============================================================================#
 # 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.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.List;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNull;
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.rhelp.core.DocResource;
import org.eclipse.statet.rhelp.core.REnvHelpConfiguration;
import org.eclipse.statet.rhelp.core.RHelpCore;
import org.eclipse.statet.rhelp.core.RHelpKeyword;
import org.eclipse.statet.rhelp.core.RHelpKeywordGroup;
import org.eclipse.statet.rhelp.core.RHelpPage;
import org.eclipse.statet.rhelp.core.RPkgHelp;
import org.eclipse.statet.rj.renv.core.BasicRLibLocation;
import org.eclipse.statet.rj.renv.core.BasicRPkgDescription;
import org.eclipse.statet.rj.renv.core.REnvConfiguration;
import org.eclipse.statet.rj.renv.core.RLibLocation;
import org.eclipse.statet.rj.renv.core.RNumVersion;
import org.eclipse.statet.rj.renv.core.RPkgDescription;


@NonNullByDefault
public class SerUtil {
	
	
	public static final int VERSION_12= 12;
	public static final int VERSION_11= 11;
	public static final int VERSION_10= 10;
	public static final int CURRENT_VERSION= VERSION_12;
	
	public static final int[] KNOWN_VERSIONS= {
			VERSION_12,
			VERSION_11,
			VERSION_10 };
	
	private static final int COMPRESS= 1 << 4;
	
	
	private static final String RHELP_SER_FILE= "rhelp.ser"; //$NON-NLS-1$
	
	
	private static class UnsupportedVersionException extends IOException {
		
		private static final long serialVersionUID= 1L;
		
		public UnsupportedVersionException(final int inputVersion) {
			super("input= " + inputVersion);
		}
		
	}
	
	public static interface Controller {
		
		Object getFileLock();
		
		boolean shouldSave();
		void onSaved();
		
	}
	
	
	public static @Nullable Path getIndexDirectoryPath(final REnvHelpConfiguration rEnvConfig) {
		try {
			final Path stateDirectory= rEnvConfig.getStateSharedDirectoryPath();
			if (stateDirectory != null) {
				return stateDirectory.resolve("index"); //$NON-NLS-1$
			}
		}
		catch (final Exception e) {}
		return null;
	}
	
	public static Path getIndexDirectoryChecked(final REnvHelpConfiguration rEnvConfig) {
		Exception e1= null;
		try {
			final Path stateDirectory= rEnvConfig.getStateSharedDirectoryPath();
			if (stateDirectory != null) {
				final Path indexDirectory= stateDirectory.resolve("index"); //$NON-NLS-1$
				if (!Files.isDirectory(indexDirectory)) {
					Files.createDirectories(indexDirectory);
				}
				return indexDirectory;
			}
		}
		catch (final Exception e) {
			e1= e;
		}
		throw new RuntimeException(
				String.format("Index directory could not be resolved: '%1$s'.",
						rEnvConfig.getStateSharedDirectory() ),
				e1 );
	}
	
	public static Path getBasicDataFilePath(final Path indexDirectory) {
		return indexDirectory.resolve(RHELP_SER_FILE);
	}
	
	public static @Nullable Path getBasicDataFilePath(final REnvHelpConfiguration rEnvConfig) {
		final Path directory= getIndexDirectoryPath(rEnvConfig);
		if (directory != null) {
			return getBasicDataFilePath(directory);
		}
		return null;
	}
	
	
	public SerUtil() {
	}
	
	
	public boolean canRead(final int version, final String type) {
		switch (version) {
		case VERSION_12:
		case VERSION_11:
			return true;
		case VERSION_10:
			return (type == REnvConfiguration.SHARED_SERVER);
		default:
			return false;
		}
	}
	
	
	public boolean save(final REnvHelpConfiguration rEnvConfig, final REnvHelpImpl help,
			final Controller controller) {
		try {
			final Path directory= getIndexDirectoryChecked(rEnvConfig);
			final Path newFile= directory.resolve(RHELP_SER_FILE + ".new"); //$NON-NLS-1$
			
			Files.deleteIfExists(newFile);
			try (final DataStream out= DataStream.get(new BufferedOutputStream(
					Files.newOutputStream(newFile, StandardOpenOption.CREATE_NEW) ))) {
				save(help, out, COMPRESS);
				out.flush();
			}
			
			synchronized (controller.getFileLock()) {
				if (!controller.shouldSave()) {
					return false;
				}
				final Path serFile= directory.resolve(RHELP_SER_FILE);
				Files.move(newFile, serFile, StandardCopyOption.REPLACE_EXISTING);
				controller.onSaved();
				return true;
			}
		}
		catch (final Exception e) {
			RHelpCoreInternals.log(new ErrorStatus(RHelpCore.BUNDLE_ID,
					String.format("An error occurred when saving R help data for '%1$s'.",
							rEnvConfig.getName() ),
					e ));
			return false;
		}
	}
	
	public boolean save(final REnvHelpConfiguration rEnvConfig, final InputStream in,
			final Controller controller) {
		try {
			final Path directory= getIndexDirectoryChecked(rEnvConfig);
			final Path newFile= directory.resolve(RHELP_SER_FILE + ".new"); //$NON-NLS-1$
			
			Files.copy(in, newFile, StandardCopyOption.REPLACE_EXISTING);
			
			synchronized (controller.getFileLock()) {
				if (!controller.shouldSave()) {
					return false;
				}
				final Path serFile= directory.resolve(RHELP_SER_FILE);
				Files.move(newFile, serFile, StandardCopyOption.REPLACE_EXISTING);
				controller.onSaved();
				return true;
			}
		}
		catch (final Exception e) {
			RHelpCoreInternals.log(new ErrorStatus(RHelpCore.BUNDLE_ID,
					String.format("An error occurred when saving R help data for '%1$s'.",
							rEnvConfig.getName() ),
					e ));
			return false;
		}
	}
	
	public long getStamp(final REnvHelpConfiguration rEnvConfig) {
		try {
			final Path serFile= getBasicDataFilePath(rEnvConfig);
			if (!Files.isRegularFile(serFile)) {
				return REnvHelpImpl.NOT_AVAILABLE_STAMP;
			}
			
			try (final DataStream in= DataStream.get(new BufferedInputStream(
					Files.newInputStream(serFile), 64 ))) {
				final int version= in.readVersion();
				if (version != CURRENT_VERSION
						&& !canRead(version, rEnvConfig.getStateSharedType())) {
					return REnvHelpImpl.NOT_AVAILABLE_STAMP;
				}
				return in.readLong();
			}
		}
		catch (final Throwable e) {
			if (e instanceof Error && !(e instanceof UnsupportedVersionException)) {
				throw (Error) e;
			}
			RHelpCoreInternals.log(new ErrorStatus(RHelpCore.BUNDLE_ID,
					String.format("An error occurred when loading R help data for '%1$s'.",
							rEnvConfig.getName() ),
					e ));
			return REnvHelpImpl.NOT_AVAILABLE_STAMP;
		}
	}
	
	public @Nullable REnvHelpImpl load(final REnvHelpConfiguration rEnvConfig) {
		try {
			final Path serFile= getBasicDataFilePath(rEnvConfig);
			if (!Files.isRegularFile(serFile)) {
				return null;
			}
			
			try (final DataStream in= DataStream.get(new BufferedInputStream(
					Files.newInputStream(serFile) ))) {
				return load(rEnvConfig, in);
			}
		}
		catch (final Throwable e) {
			if (e instanceof Error) {
				throw (Error) e;
			}
			RHelpCoreInternals.log(new ErrorStatus(RHelpCore.BUNDLE_ID,
					String.format("An error occurred when loading R help data for '%1$s'.",
							rEnvConfig.getName() ),
					e ));
			return null;
		}
	}
	
	public void save(final REnvHelpImpl help, final DataStream out, final int flags)
			throws IOException {
		out.writeVersion(CURRENT_VERSION);
		out.writeLong(help.getStamp());
		
		out.writeInt(flags);
		if ((flags & COMPRESS) != 0) {
			out.enableCompression();
		}
		
		out.writeString(help.getDocDir());
		{	final ImList<DocResource> resources= help.getManuals();
			final int count= resources.size();
			out.writeInt(count);
			for (int i= 0; i < count; i++) {
				saveDocResource(resources.get(i), out);
			}
		}
		{	final ImList<DocResource> resources= help.getMiscResources();
			final int count= resources.size();
			out.writeInt(count);
			for (int i= 0; i < count; i++) {
				saveDocResource(resources.get(i), out);
			}
		}
		
		{	final List<RHelpKeywordGroup> keywordGroups= help.getKeywords();
			final int count= keywordGroups.size();
			out.writeInt(count);
			for (int i= 0; i < keywordGroups.size(); i++) {
				saveKeywordGroup(keywordGroups.get(i), out);
			}
		}
		{	final List<RPkgHelp> packages= help.getPkgs();
			final int count= packages.size();
			out.writeInt(count);
			for (int i= 0; i < packages.size(); i++) {
				savePackage(packages.get(i), out);
			}
		}
	}
	
	public REnvHelpImpl load(final REnvHelpConfiguration rEnvConfig, final DataStream in)
			throws IOException {
		final int version= in.readVersion();
		if (version != CURRENT_VERSION
				&& !canRead(version, rEnvConfig.getStateSharedType())) {
			throw new UnsupportedVersionException(version);
		}
		
		final long stamp= in.readLong();
		
		final int flags= in.readInt();
		if ((flags & COMPRESS) != 0) {
			in.enableCompression();
		}
		
		final String docDir= in.readString();
		final ImList<DocResource> manuals;
		{	final int count= in.readInt();
			final DocResource[] array= new @NonNull DocResource[count];
			for (int i= 0; i < count; i++) {
				array[i]= readDocResource(in);
			}
			manuals= ImCollections.newList(array);
		}
		final ImList<DocResource> miscRes;
		{	final int count= in.readInt();
			final DocResource[] array= new @NonNull DocResource[count];
			for (int i= 0; i < count; i++) {
				array[i]= readDocResource(in);
			}
			miscRes= ImCollections.newList(array);
		}
		
		final ImList<RHelpKeywordGroup> keywordGroups;
		{	final int count= in.readInt();
			final RHelpKeywordGroup[] array= new @NonNull RHelpKeywordGroup[count];
			for (int i= 0; i < count; i++) {
				array[i]= loadKeywordGroup(in);
			}
			keywordGroups= ImCollections.newList(array);
		}
		
		final ImList<RPkgHelp> pkgHelps;
		{	final int count= in.readInt();
			final RPkgHelp[] array= new @NonNull RPkgHelp[count];
			for (int i= 0; i < count; i++) {
				array[i]= loadPackage(rEnvConfig, in);
			}
			pkgHelps= ImCollections.newList(array);
		}
		
		return new REnvHelpImpl(rEnvConfig.getREnv(), version, stamp,
				docDir, manuals, miscRes,
				keywordGroups, pkgHelps );
	}
	
	
	private void saveDocResource(final DocResource res,
			final DataStream out) throws IOException {
		out.writeString(res.getTitle());
		out.writeString(res.getPath());
		out.writeString(res.getPdfPath());
	}
	
	private DocResource readDocResource(final DataStream in) throws IOException {
		return new DocResource(
				in.readNonNullString(),
				in.readNonNullString(),
				in.readString() );
	}
	
	
	private void saveKeywordGroup(final RHelpKeywordGroup group,
			final DataStream out) throws IOException {
		out.writeString(group.getLabel());
		out.writeString(group.getDescription());
		final List<RHelpKeyword> keywords= group.getNestedKeywords();
		final int count= keywords.size();
		out.writeInt(count);
		for (int i= 0; i < count; i++) {
			saveKeyword(keywords.get(i), out);
		}
	}
	
	private RHelpKeywordGroup loadKeywordGroup(final DataStream in) throws IOException {
		final String label= in.readNonNullString();
		final String description= in.readNonNullString();
		final int count= in.readInt();
		final RHelpKeyword[] keywords= new @NonNull RHelpKeyword[count];
		for (int i= 0; i < count; i++) {
			keywords[i]= loadKeyword(in);
		}
		return new RHelpKeywordGroupImpl(label, description, ImCollections.newList(keywords));
	}
	
	private void saveKeyword(final RHelpKeyword keyword, final DataStream out)
			throws IOException {
		out.writeString(keyword.getKeyword());
		out.writeString(keyword.getDescription());
		final List<RHelpKeyword> nestedKeywords= keyword.getNestedKeywords();
		final int count= nestedKeywords.size();
		out.writeInt(count);
		for (int i= 0; i < nestedKeywords.size(); i++) {
			saveKeyword(nestedKeywords.get(i), out);
		}
	}
	
	private RHelpKeyword loadKeyword(final DataStream in)
			throws IOException {
		final String keyword= in.readNonNullString();
		final String description= in.readNonNullString();
		final int n= in.readInt();
		final RHelpKeyword[] nestedKeywords= new @NonNull RHelpKeyword[n];
		for (int i= 0; i < n; i++) {
			nestedKeywords[i]= loadKeyword(in);
		}
		return new RHelpKeywordImpl(keyword, description, ImCollections.newList(nestedKeywords));
	}
	
	private void savePackage(final RPkgHelp pkgHelp, final DataStream out)
			throws IOException {
		savePkgDescription(pkgHelp.getPkgDescription(), out);
		
		final List<RHelpPage> pages= pkgHelp.getPages();
		final int nPages= pages.size();
		out.writeInt(nPages);
		for (int i= 0; i < nPages; i++) {
			savePage(pages.get(i), out);
		}
	}
	
	private RPkgHelp loadPackage(final REnvHelpConfiguration rEnvConfig, final DataStream in)
			throws IOException {
		final RPkgDescription pkgDescription= loadPkgDescription(rEnvConfig, in);
		
		final int nPages= in.readInt();
		final RHelpPage[] pages= new @NonNull RHelpPage[nPages];
		final RPkgHelpImpl pkg= new RPkgHelpImpl(pkgDescription, rEnvConfig.getREnv());
		for (int i= 0; i < nPages; i++) {
			pages[i]= loadPage(pkg, in);
		}
		pkg.setPages(ImCollections.newList(pages));
		return pkg;
	}
	
	private void savePkgDescription(final RPkgDescription pkgDescription,
			final DataStream out) throws IOException {
		out.writeString(pkgDescription.getName());
		out.writeString(pkgDescription.getVersion().toString());
		out.writeString(pkgDescription.getTitle());
		out.writeString(pkgDescription.getDescription());
		out.writeString(pkgDescription.getAuthor());
		out.writeString(pkgDescription.getMaintainer());
		out.writeString(pkgDescription.getUrl());
		out.writeString(pkgDescription.getBuilt());
		out.writeString(pkgDescription.getLibLocation().getDirectory());
	}
	
	private RPkgDescription loadPkgDescription(final REnvHelpConfiguration rEnvConfig,
			final DataStream in) throws IOException {
		final String name= in.readNonNullString().intern();
		final String version= in.readNonNullString();
		final String title= in.readNonNullString();
		final String description= in.readNonNullString();
		final String author= in.readString();
		final String maintainer= in.readString();
		final String url= in.readString();
		final String built= in.readNonNullString();
		final RLibLocation libLocation= getLibLocationSafe(rEnvConfig, in.readNonNullString());
		
		return new BasicRPkgDescription(name, RNumVersion.create(version),
				title, description,
				author, maintainer,
				url,
				built, libLocation);
	}
	
	private RLibLocation getLibLocationSafe(final REnvHelpConfiguration rEnvConfig, final String directory) {
		RLibLocation libLocation= rEnvConfig.getRLibLocationByDirectory(directory);
		if (libLocation == null) {
			libLocation= new BasicRLibLocation(RLibLocation.MISSING, directory, null);
		}
		return libLocation;
	}
	
	private void savePage(final RHelpPage page, final DataStream out)
			throws IOException {
		if (out.getVersion() >= VERSION_12) {
			out.writeByte(RHelpPageImpl.createFlags(page.isInternal()));
		}
		out.writeString(page.getName());
		{	final ImList<String> topics= page.getTopics();
			final int nTopics= topics.size();
			out.writeInt(nTopics);
			for (int i= 0; i < nTopics; i++) {
				final String topic= topics.get(i);
				out.writeString((topic == page.getName()) ? null : topic);
			}
		}
		out.writeString(page.getTitle());
	}
	
	private RHelpPage loadPage(final RPkgHelp pkg, final DataStream in)
			throws IOException {
		final byte pageFlags= (in.getVersion() >= VERSION_12) ?
				in.readByte() :
				0;
		final String name= in.readNonNullString().intern();
		final ImList<String> topics;
		{	final int nTopics= in.readInt();
			final String[] array= new @NonNull String[nTopics];
			for (int i= 0; i < array.length; i++) {
				final String topic= in.readString();
				array[i]= (topic == null) ? name : topic.intern();
			}
			topics= ImCollections.newList(array);
		}
		final String title= in.readNonNullString();
		return new RHelpPageImpl(pkg, name, pageFlags, topics, title);
	}
	
}
