/*=============================================================================#
 # Copyright (c) 2012, 2019 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.r.core.pkgmanager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.osgi.util.NLS;

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.r.core.RCore;
import org.eclipse.statet.r.core.pkgmanager.IRPkgData;
import org.eclipse.statet.r.core.pkgmanager.IRPkgInfo;
import org.eclipse.statet.r.core.pkgmanager.ISelectedRepos;
import org.eclipse.statet.r.core.pkgmanager.RPkgInfo;
import org.eclipse.statet.r.core.pkgmanager.RPkgUtils;
import org.eclipse.statet.r.core.pkgmanager.RRepo;
import org.eclipse.statet.rj.data.RArray;
import org.eclipse.statet.rj.data.RCharacterStore;
import org.eclipse.statet.rj.data.RDataUtils;
import org.eclipse.statet.rj.data.UnexpectedRDataException;
import org.eclipse.statet.rj.renv.core.BasicRPkg;
import org.eclipse.statet.rj.renv.core.BasicRPkgCompilation;
import org.eclipse.statet.rj.renv.core.REnv;
import org.eclipse.statet.rj.renv.core.RLibLocation;
import org.eclipse.statet.rj.renv.core.RNumVersion;
import org.eclipse.statet.rj.renv.core.RPkg;
import org.eclipse.statet.rj.renv.core.RPkgCompilation;
import org.eclipse.statet.rj.renv.core.RPkgList;
import org.eclipse.statet.rj.renv.runtime.RLibLocationInfo;
import org.eclipse.statet.rj.renv.runtime.RuntimeRLibPaths;
import org.eclipse.statet.rj.services.FunctionCall;
import org.eclipse.statet.rj.services.RService;


final class RPkgScanner {
	
	private static final String AVAIL_LIST_FNAME= "rj:::renv.getAvailPkgs"; //$NON-NLS-1$
	private static final int AVAIL_LIST_COUNT1= 9;
	private static final int AVAIL_LIST_IDX1_NAME= 0;
	private static final int AVAIL_LIST_IDX1_VERSION= 1;
	private static final int AVAIL_LIST_IDX1_PRIORITY= 2;
	private static final int AVAIL_LIST_IDX1_LICENSE= 3;
	private static final int AVAIL_LIST_IDX1_DEPENDS= 4;
	private static final int AVAIL_LIST_IDX1_IMPORTS= 5;
	private static final int AVAIL_LIST_IDX1_LINKINGTO= 6;
	private static final int AVAIL_LIST_IDX1_SUGGESTS= 7;
	private static final int AVAIL_LIST_IDX1_ENHANCES= 8;
	
	private static final String INST_LIST_FNAME= "rj:::renv.getInstPkgs"; //$NON-NLS-1$
	private static final int INST_LIST_COUNT1= 4;
	private static final int INST_LIST_IDX1_NAME= 0;
	private static final int INST_LIST_IDX1_VERSION= 1;
	private static final int INST_LIST_IDX1_TITLE= 2;
	private static final int INST_LIST_IDX1_BUILT= 3;
	
	private static final String INST_DETAIL_FNAME= "rj:::renv.getInstPkgDetail"; //$NON-NLS-1$
	private static final int INST_DETAIL_LENGTH= 7;
	private static final int INST_DETAIL_IDX_PRIORITY= 0;
	private static final int INST_DETAIL_IDX_LICENSE= 1;
	private static final int INST_DETAIL_IDX_DEPENDS= 2;
	private static final int INST_DETAIL_IDX_IMPORTS= 3;
	private static final int INST_DETAIL_IDX_LINKINGTO= 4;
	private static final int INST_DETAIL_IDX_SUGGESTS= 5;
	private static final int INST_DETAIL_IDX_ENHANCES= 6;
	
	
	private static List<RPkg> parsePkgRefs(final String s) {
		if (s == null || s.isEmpty()) {
			return Collections.emptyList();
		}
		final List<RPkg> list= new ArrayList<>(4);
		String name= null;
		String version= null;
		boolean ws;
		final StringBuilder sb= new StringBuilder();
		ITER_S: for (int i= 0; i <= s.length();) {
			int c= (i < s.length()) ? s.charAt(i) : -1;
			
			if (c == -1 || c == ',') {
				if (name != null) {
					list.add(new BasicRPkg(name, RNumVersion.create(version)));
				}
				name= null;
				version= null;
				i++;
				continue ITER_S;
			}
			if (Character.isLetterOrDigit(c)) {
				if (name != null) {
					// ?
				}
				name= null;
				version= null;
				int j= i + 1;
				while (true) {
					c= (j < s.length()) ? s.charAt(j) : -1;
					if (c < 0 || Character.isWhitespace(c) || c == '(' || c == ',') {
						name= s.substring(i, j).intern();
						i= j;
						continue ITER_S;
					}
					j++;
				}
			}
			if (c == '(') {
				if (name == null || version != null) {
					// ?
					name= null;
					version= null;
				}
				sb.setLength(0);
				ws= false;
				int j= ++i;
				while (true) {
					c= (j < s.length()) ? s.charAt(j) : -1;
					if (c < 0 || c == ')') {
						version= sb.toString();
						i= j + 1;
						continue ITER_S;
					}
					if (Character.isWhitespace(c)) {
						ws= true;
					}
					else {
						if (ws) {
							sb.append(' ');
							ws= false;
						}
						sb.append((char) c);
					}
					j++;
				}
			}
			
			i++;
			continue ITER_S;
		}
		return list;
	}
	
	
	private final BasicRPkgCompilation<IRPkgData> expectedPkgs= new BasicRPkgCompilation<IRPkgData>(4) {
		@Override
		protected RPkgList<IRPkgData> newPkgList() {
			return new RPkgListImpl<>(4);
		}
	};
	
	
	public RPkgScanner() {
	}
	
	
	void addExpectedPkg(final RLibLocation location, final IRPkgData pkg) {
		final String path= location.getDirectory();
		final RPkgListImpl<IRPkgData> list= (RPkgListImpl<IRPkgData>) this.expectedPkgs.getOrAdd(path);
		list.set(pkg);
	}
	
	private void clearExpected() {
		final List<RPkgList<IRPkgData>> all= this.expectedPkgs.getAll();
		for (final RPkgList<IRPkgData> list : all) {
			((RPkgListImpl<IRPkgData>) list).clear();
		}
	}
	
	
	RPkgCompilation<IRPkgData> loadAvailable(final REnv rEnv, final ISelectedRepos repoSettings,
			final RService r, final ProgressMonitor m) throws StatusException {
		m.beginSubTask("Loading available R packages...");
		try {
			final RCharacterStore repos= RDataUtils.checkRCharVector(r.evalData(
					"options('repos')[[1L]]", m)).getData(); //$NON-NLS-1$
			final int l= RDataUtils.checkIntLength(repos);
			
			final BasicRPkgCompilation<IRPkgData> newAvailable= new BasicRPkgCompilation<>(l);
			for (int idxRepos= 0; idxRepos < l; idxRepos++) {
				final String repoURL= repos.getChar(idxRepos);
				if (repoURL == null || repoURL.isEmpty()) {
					continue;
				}
				final RRepo repo= Util.getRepoByURL(repoSettings.getRepos(), repoURL);
				m.beginSubTask(NLS.bind("Loading available R packages from {0}...", repoURL));
				
				RArray<RCharacterStore> data;
				{	final FunctionCall call= r.createFunctionCall(AVAIL_LIST_FNAME);
					call.addChar("repo", repoURL); //$NON-NLS-1$
					if (repo.getPkgType() != null) {
						final String key= RPkgUtils.getPkgTypeInstallKey(r.getPlatform(), repo.getPkgType());
						if (key == null) {
							continue;
						}
					}
					data= RDataUtils.checkRCharArray(call.evalData(m), 2);
					RDataUtils.checkColumnCountEqual(data, AVAIL_LIST_COUNT1);
				}
				
				final RCharacterStore store= data.getData();
				final int nPkgs= data.getDim().getInt(0);
				final RPkgListImpl<IRPkgData> list= new RPkgListImpl<>(nPkgs);
				newAvailable.add(repo.getId(), list);
				
				for (int idxPkgs= 0; idxPkgs < nPkgs; idxPkgs++) {
					String name= store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkgs, AVAIL_LIST_IDX1_NAME));
					final String version= store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkgs, AVAIL_LIST_IDX1_VERSION));
					if (name != null && !name.isEmpty() && version != null) {
						name= name.intern();
						final RPkgData pkg= new RPkgData(name, RNumVersion.create(version), repo.getId());
						
						pkg.setLicense(store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkgs, AVAIL_LIST_IDX1_LICENSE)));
						
						pkg.setDepends(RPkgScanner.parsePkgRefs(store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkgs, AVAIL_LIST_IDX1_DEPENDS))));
						pkg.setImports(RPkgScanner.parsePkgRefs(store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkgs, AVAIL_LIST_IDX1_IMPORTS))));
						pkg.setLinkingTo(RPkgScanner.parsePkgRefs(store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkgs, AVAIL_LIST_IDX1_LINKINGTO))));
						pkg.setSuggests(RPkgScanner.parsePkgRefs(store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkgs, AVAIL_LIST_IDX1_SUGGESTS))));
						pkg.setEnhances(RPkgScanner.parsePkgRefs(store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkgs, AVAIL_LIST_IDX1_ENHANCES))));
						
						pkg.setPriority(store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkgs, AVAIL_LIST_IDX1_PRIORITY)));
						
						list.add(pkg);
					}
				}
			}
			
			return newAvailable;
		}
		catch (final UnexpectedRDataException | StatusException e) {
			throw new StatusException(new ErrorStatus(RCore.BUNDLE_ID,
					"An error occurred when loading list of available R packages.",
					e ));
		}
	}
	
	RPkgCompilation<IRPkgInfo> loadInstalled(final RuntimeRLibPaths rLibPaths, final boolean[] update,
			final Change event,
			final RService r, final ProgressMonitor m) throws StatusException {
		m.beginSubTask("Updating installed R packages...");
		try {
			final BasicRPkgCompilation<IRPkgInfo> newInstalled= new BasicRPkgCompilation<>(
					rLibPaths.getRLibLocations().size() );
			final RPkgCompilation<IRPkgInfo> prevInstalled= (RPkgCompilation<IRPkgInfo>)
					((event.oldPkgs != null) ? event.oldPkgs.getInstalled() : null);
			final RPkgChangeSet changeSet= new RPkgChangeSet();
			event.installedPkgs= changeSet;
			for (final RLibLocation libLocation : rLibPaths.getRLibLocations()) {
				final RLibLocationInfo locationInfo= rLibPaths.getInfo(libLocation);
				if (locationInfo == null || locationInfo.getLibPathsIndex() < 0) {
					continue;
				}
				if (newInstalled.getBySource(libLocation.getDirectory()) != null) {
					continue;
				}
				if (update == null || update[locationInfo.getLibPathsIndex()] || prevInstalled == null) {
					final RArray<RCharacterStore> data;
					{	final FunctionCall call= r.createFunctionCall(INST_LIST_FNAME);
						call.addChar("lib", locationInfo.getDirectoryRPath()); //$NON-NLS-1$
						data= RDataUtils.checkRCharArray(call.evalData(m), 2);
						RDataUtils.checkColumnCountEqual(data, INST_LIST_COUNT1);
					}
					final RCharacterStore store= data.getData();
					final int nPkgs= data.getDim().getInt(0);
					
					final RPkgList<IRPkgInfo> oldList= (prevInstalled != null) ?
							prevInstalled.getBySource(libLocation.getDirectory()) : null;
					final RPkgListImpl<IRPkgInfo> newList= new RPkgListImpl<>(nPkgs);
					final RPkgList<IRPkgData> expectedList= this.expectedPkgs.getBySource(libLocation.getDirectory());
					for (int idxPkg= 0; idxPkg < nPkgs; idxPkg++) {
						String name= store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkg, INST_LIST_IDX1_NAME));
						final String version= store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkg, INST_LIST_IDX1_VERSION));
						if (name != null && !name.isEmpty() && version != null && !version.isEmpty()) {
							name= name.intern();
							String built= store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkg, INST_LIST_IDX1_BUILT));
							if (built == null) {
								built= ""; //$NON-NLS-1$
							}
							final IRPkgInfo oldPkg= (oldList != null) ? oldList.get(name) : null;
							final IRPkgInfo newPkg;
							final boolean changed= (oldPkg == null
									|| !oldPkg.getVersion().toString().equals(version)
									|| !oldPkg.getBuilt().equals(built) );
							
							if (!changed) {
								newPkg= oldPkg;
							}
							else {
								final IRPkgData expectedData =
										(expectedList != null) ? expectedList.get(name) : null;
								newPkg= new RPkgInfo(name, RNumVersion.create(version), built,
										store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkg, INST_LIST_IDX1_TITLE)),
										libLocation,
										0,
										event.stamp,
										(expectedData != null) ? expectedData.getRepoId() : null );
								
								changeSet.names.add(name);
								if (oldPkg == null) {
									changeSet.added.add(newPkg);
								}
								else {
									changeSet.changed.add(oldPkg);
								}
							}
							
							newList.add(newPkg);
						}
					}
					if (oldList != null) {
						int i= 0, j= 0;
						final int in= oldList.size(), jn= newList.size();
						while (i < in) {
							final IRPkgInfo oldPkg= oldList.get(i++);
							final String name= oldPkg.getName();
							if (j < jn) {
								if (newList.get(j).getName() == name) {
									j++;
									continue;
								}
								final int idx= newList.indexOf(name, j + 1);
								if (idx >= 0) {
									j= idx + 1;
									continue;
								}
							}
							changeSet.names.add(name);
							changeSet.deleted.add(oldPkg);
						}
					}
					
					newInstalled.add(libLocation.getDirectory(), newList);
				}
				else {
					final RPkgList<IRPkgInfo> prevList= prevInstalled.getBySource(libLocation.getDirectory());
					if (prevList != null) {
						newInstalled.add(libLocation.getDirectory(), prevList);
					}
					else {
						// error/warning?
					}
				}
			}
			
			clearExpected();
			
			return newInstalled;
		}
		catch (final UnexpectedRDataException | StatusException e) {
			throw new StatusException(new ErrorStatus(RCore.BUNDLE_ID,
					"An error occurred when loading list of installed R packages.",
					e ));
		}
	}
	
	void updateInstFull(final RuntimeRLibPaths rLibPaths, final boolean[] update,
			final FullRPkgSet newPkgs, final Change event,
			final RService r, final ProgressMonitor m) throws StatusException {
		m.beginSubTask("Updating installed R packages...");
		try {
			final FullRPkgSet oldFullPkgs= (event.oldPkgs instanceof FullRPkgSet) ?
					(FullRPkgSet) event.oldPkgs : null;
			final RPkgChangeSet changeSet= new RPkgChangeSet();
			event.installedPkgs= changeSet;
			for (final RLibLocation location : rLibPaths.getRLibLocations()) {
				final RLibLocationInfo locationInfo= rLibPaths.getInfo(location);
				if (locationInfo == null || locationInfo.getLibPathsIndex() < 0) {
					continue;
				}
				if (update == null || update[locationInfo.getLibPathsIndex()] || oldFullPkgs == null) {
					final RArray<RCharacterStore> data;
					{	final FunctionCall call= r.createFunctionCall(INST_LIST_FNAME);
						call.addChar("lib", locationInfo.getDirectoryRPath()); //$NON-NLS-1$
						data= RDataUtils.checkRCharArray(call.evalData(m), 2);
						RDataUtils.checkColumnCountEqual(data, INST_LIST_COUNT1);
					}
					final RCharacterStore store= data.getData();
					final int nPkgs= data.getDim().getInt(0);
					
					final RPkgList<? extends IRPkgInfo> oldList= (event.oldPkgs != null) ?
							event.oldPkgs.getInstalled().getBySource(location.getDirectory()) : null;
					final RPkgListImpl<RPkgInfoAndData> newList= new RPkgListImpl<>(nPkgs);
					final RPkgList<IRPkgData> expectedList= this.expectedPkgs.getBySource(location.getDirectory());
					for (int idxPkg= 0; idxPkg < nPkgs; idxPkg++) {
						String name= store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkg, INST_LIST_IDX1_NAME));
						final String version= store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkg, INST_LIST_IDX1_VERSION));
						if (name != null && !name.isEmpty() && version != null && !version.isEmpty()) {
							name= name.intern();
							String built= store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkg, INST_LIST_IDX1_BUILT));
							if (built == null) {
								built= ""; //$NON-NLS-1$
							}
							final IRPkgInfo oldPkg= (oldList != null) ? oldList.get(name) : null;
							final RPkgInfoAndData newPkg;
							final boolean changed= (oldPkg == null
									|| !oldPkg.getVersion().toString().equals(version)
									|| !oldPkg.getBuilt().equals(built) );
							
							if (!changed && (oldPkg instanceof RPkgInfoAndData)) {
								newPkg= (RPkgInfoAndData) oldPkg;
							}
							else {
								final IRPkgData expectedData= (changed && expectedList != null) ?
										expectedList.get(name) : null;
								newPkg= new RPkgInfoAndData(name,
										(!changed) ? oldPkg.getVersion() : RNumVersion.create(version),
										built,
										store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkg, INST_LIST_IDX1_TITLE)),
										location,
										(!changed) ? oldPkg.getFlags() : 0,
										(!changed) ? oldPkg.getInstallStamp() : event.stamp,
										(!changed) ? oldPkg.getRepoId() : ((expectedData != null) ? expectedData.getRepoId() : null) );
								
								RCharacterStore detail;
								{	final FunctionCall call= r.createFunctionCall(INST_DETAIL_FNAME);
									call.addChar("lib", locationInfo.getDirectoryRPath()); //$NON-NLS-1$
									call.addChar("name", name); //$NON-NLS-1$
									detail= RDataUtils.checkRCharVector(call.evalData(m)).getData();
									RDataUtils.checkLengthEqual(detail, INST_DETAIL_LENGTH);
								}
								
								newPkg.setPriority(detail.getChar(INST_DETAIL_IDX_PRIORITY));
								newPkg.setLicense(detail.getChar(INST_DETAIL_IDX_LICENSE));
								
								newPkg.setDepends(RPkgScanner.parsePkgRefs(detail.getChar(INST_DETAIL_IDX_DEPENDS)));
								newPkg.setImports(RPkgScanner.parsePkgRefs(detail.getChar(INST_DETAIL_IDX_IMPORTS)));
								newPkg.setLinkingTo(RPkgScanner.parsePkgRefs(detail.getChar(INST_DETAIL_IDX_LINKINGTO)));
								newPkg.setSuggests(RPkgScanner.parsePkgRefs(detail.getChar(INST_DETAIL_IDX_SUGGESTS)));
								newPkg.setEnhances(RPkgScanner.parsePkgRefs(detail.getChar(INST_DETAIL_IDX_ENHANCES)));
								
								if (changed) {
									changeSet.names.add(name);
									if (oldPkg == null) {
										changeSet.added.add(newPkg);
									}
									else {
										changeSet.changed.add(oldPkg);
									}
								}
							}
							
							newList.add(newPkg);
						}
					}
					if (oldList != null) {
						int i= 0, j= 0;
						final int in= oldList.size(), jn= newList.size();
						while (i < in) {
							final IRPkgInfo oldPkg= oldList.get(i++);
							final String name= oldPkg.getName();
							if (j < jn) {
								if (newList.get(j).getName() == name) {
									j++;
									continue;
								}
								final int idx= newList.indexOf(name, j + 1);
								if (idx >= 0) {
									j= idx + 1;
									continue;
								}
							}
							changeSet.names.add(name);
							changeSet.deleted.add(oldPkg);
						}
					}
					
					newPkgs.getInstalled().add(location.getDirectory(), newList);
				}
				else {
					newPkgs.getInstalled().add(location.getDirectory(),
							oldFullPkgs.getInstalled().getBySource(location.getDirectory()) );
				}
			}
			return;
		}
		catch (final UnexpectedRDataException | StatusException e) {
			throw new StatusException(new ErrorStatus(RCore.BUNDLE_ID,
					"An error occurred when loading list of installed R packages.",
					e ));
		}
	}
	
}
