/*=============================================================================#
 # 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.rj.renv.runtime;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullElse;

import static org.eclipse.statet.internal.rj.renv.core.REnvCoreInternals.BUNDLE_ID;

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.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.BasicRPkgBuilt;
import org.eclipse.statet.rj.renv.core.BasicRPkgCompilation;
import org.eclipse.statet.rj.renv.core.BasicRPkgList;
import org.eclipse.statet.rj.renv.core.RLibLocation;
import org.eclipse.statet.rj.renv.core.RNumVersion;
import org.eclipse.statet.rj.renv.core.RPkgBuilt;
import org.eclipse.statet.rj.renv.core.RPkgCompilation;
import org.eclipse.statet.rj.renv.core.RPkgList;
import org.eclipse.statet.rj.services.FunctionCall;
import org.eclipse.statet.rj.services.RService;


@NonNullByDefault
public class RuntimeRPkgInfoLoader {
	
	
	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;
	
	
	public RuntimeRPkgInfoLoader() {
	}
	
	
	public RPkgCompilation<RPkgBuilt> loadInstalled(final RuntimeRLibPaths rLibPaths,
			final boolean @Nullable [] update, final @Nullable RPkgCompilation<RPkgBuilt> prevInstalled,
//			final Change event,
			final RService r, final ProgressMonitor m) throws StatusException {
		m.beginSubTask("Updating installed R packages...");
		try {
			final BasicRPkgCompilation<RPkgBuilt> newInstalled= new BasicRPkgCompilation<>(
					rLibPaths.getRLibLocations().size() );
//			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<RPkgBuilt> oldList= (prevInstalled != null) ?
							prevInstalled.getBySource(libLocation.getDirectory()) : null;
					final BasicRPkgList<RPkgBuilt> newList= new BasicRPkgList<>(nPkgs);
					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();
							final String built= nonNullElse(
									store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkg, INST_LIST_IDX1_BUILT)),
									"" ); //$NON-NLS-1$
							final RPkgBuilt oldPkg= (oldList != null) ? oldList.get(name) : null;
							final RPkgBuilt newPkg;
							if (oldPkg != null
									&& oldPkg.getVersion().toString().equals(version)
									&& oldPkg.getBuilt().equals(built) ) {
								newPkg= oldPkg;
							}
							else {
								final String title= nonNullElse(
										store.getChar(RDataUtils.getDataIdx(nPkgs, idxPkg, INST_LIST_IDX1_TITLE)),
										"" ); //$NON-NLS-1$
								newPkg= new BasicRPkgBuilt(name,
										RNumVersion.create(version), built,
										title, libLocation );
								
//								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 RPkgBuilt 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<RPkgBuilt> prevList= prevInstalled.getBySource(libLocation.getDirectory());
					if (prevList != null) {
						newInstalled.add(libLocation.getDirectory(), prevList);
					}
					else {
						// error/warning?
					}
				}
			}
			
			return newInstalled;
		}
		catch (final UnexpectedRDataException | StatusException e) {
			throw new StatusException(new ErrorStatus(BUNDLE_ID,
					"An error occurred when loading list of installed R packages.",
					e ));
		}
	}
	
}
