/*=============================================================================#
 # Copyright (c) 2007, 2021 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.sourcemodel;

import java.util.List;

import com.ibm.icu.text.DecimalFormat;

import org.eclipse.core.runtime.IProgressMonitor;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.string.InternStringCache;
import org.eclipse.statet.jcommons.string.StringFactory;
import org.eclipse.statet.jcommons.text.core.input.OffsetStringParserInput;
import org.eclipse.statet.jcommons.text.core.input.StringParserInput;
import org.eclipse.statet.jcommons.text.core.input.TextParserInput;

import org.eclipse.statet.ltk.ast.core.AstInfo;
import org.eclipse.statet.ltk.core.SourceContent;
import org.eclipse.statet.ltk.issues.core.ProblemRequestor;
import org.eclipse.statet.ltk.model.core.ModelManager;
import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
import org.eclipse.statet.ltk.model.core.impl.BasicSourceModelStamp;
import org.eclipse.statet.r.core.model.RChunkElement;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.model.RSourceUnit;
import org.eclipse.statet.r.core.model.RSourceUnitModelInfo;
import org.eclipse.statet.r.core.model.build.RProblemReporter;
import org.eclipse.statet.r.core.model.build.RSourceUnitModelContainer;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;
import org.eclipse.statet.r.core.rsource.ast.RParser;
import org.eclipse.statet.r.core.rsource.ast.RoxygenParser;
import org.eclipse.statet.r.core.rsource.ast.SourceComponent;


/**
 * Worker for r model manager
 */
public class RReconciler {
	
	
	private static final boolean LOG_TIME= false;
	
	protected static class Data {
		
		public final RSourceUnitModelContainer adapter;
		public final SourceContent content;
		
		public AstInfo ast;
		
		public RSourceUnitModelInfo oldModel;
		public RSourceUnitModelInfo newModel;
		
		public Data(final RSourceUnitModelContainer adapter, final IProgressMonitor monitor) {
			this.adapter= adapter;
			this.content= adapter.getParseContent(monitor);
		}
		
	}
	
	
	private final RModelManagerImpl rManager;
	protected boolean stop= false;
	
	private final Object raLock= new Object();
	private final StringFactory raAstStringCache;
	private final StringParserInput raInput= new StringParserInput(0x1000);
	private final RoxygenParser raRoxygenParser;
	
	private final Object rmLock= new Object();
	private final SourceAnalyzer rmScopeAnalyzer;
	
	private final Object rpLock= new Object();
	private final RProblemReporter rpReporter;
	
	
	public RReconciler(final RModelManagerImpl manager) {
		this.rManager= manager;
		this.raAstStringCache= new InternStringCache(0x20);
		this.raRoxygenParser= new RoxygenParser(this.raAstStringCache);
		this.rmScopeAnalyzer= new SourceAnalyzer();
		this.rpReporter= new RProblemReporter();
	}
	
	
	/** for editor reconciling */
	public void reconcile(final RSourceUnitModelContainer adapter, final int flags,
			final IProgressMonitor monitor) {
		final RSourceUnit su= adapter.getSourceUnit();
		final int type= (su.getModelTypeId().equals(RModel.R_TYPE_ID) ? su.getElementType() : 0);
		if (type == 0) {
			return;
		}
		
		final Data data= new Data(adapter, monitor);
		if (data.content == null) {
			return;
		}
		
		synchronized (this.raLock) {
			if (this.stop || monitor.isCanceled()) {
				return;
			}
			updateAst(data, monitor);
		}
		
		if (this.stop || monitor.isCanceled()
				|| (flags & 0xf) < ModelManager.MODEL_FILE) {
			return;
		}
		
		synchronized (this.rmLock) {
			if (this.stop || monitor.isCanceled()) {
				return;
			}
			final boolean updated= updateModel(data);
			
			if (this.stop) {
				return;
			}
			
			if (updated) {
				this.rManager.getEventJob().addUpdate(su, data.oldModel, data.newModel);
			}
		}
		
		if ((flags & ModelManager.RECONCILE) != 0 && data.newModel != null) {
			if (this.stop || monitor.isCanceled()) {
				return;
			}
			
			ProblemRequestor problemRequestor= null;
			synchronized (this.rpLock) {
				if (!this.stop && !monitor.isCanceled()
						&& data.newModel == adapter.getCurrentModel() ) {
					problemRequestor= adapter.createProblemRequestor();
					if (problemRequestor != null) {
						this.rpReporter.run(su, data.content,
								(RAstNode) data.ast.getRoot(), problemRequestor );
					}
				}
			}
			if (problemRequestor != null) {
				problemRequestor.finish();
			}
		}
	}
	
	public RSourceUnitModelInfo reconcile(final RSourceUnit su, final SourceUnitModelInfo modelInfo,
			final List<? extends RChunkElement> chunkElements, final List<? extends SourceComponent> inlineNodes,
			final int level, final IProgressMonitor monitor) {
		synchronized (this.rmLock) {
			return updateModel(su, modelInfo, chunkElements, inlineNodes);
		}
	}
	
	protected final void updateAst(final Data data, final IProgressMonitor monitor) {
		final BasicSourceModelStamp stamp= new BasicSourceModelStamp(data.content.getStamp());
		
		data.ast= data.adapter.getCurrentAst();
		if (data.ast != null && !stamp.equals(data.ast.getStamp())) {
			data.ast= null;
		}
		
		if (data.ast == null) {
			final long startAst;
			final long stopAst;
			startAst= System.nanoTime();
			
			final TextParserInput input;
			if (data.content.getStartOffset() != 0) {
				input= new OffsetStringParserInput(data.content.getText(), data.content.getStartOffset());
			}
			else {
				input= this.raInput.reset(data.content.getText());
			}
			
			final RParser rParser= new RParser(AstInfo.LEVEL_MODEL_DEFAULT,
					this.raAstStringCache );
			rParser.setCommentLevel(100);
			final SourceComponent sourceComponent= rParser.scanSourceRange(
					input.init(data.content.getStartOffset(), data.content.getEndOffset()),
					null );
			data.ast= new AstInfo(rParser.getAstLevel(), stamp, sourceComponent);
			
			stopAst= System.nanoTime();
			
			this.raRoxygenParser.init(
					input.init(data.content.getStartOffset(), data.content.getEndOffset()));
			this.raRoxygenParser.update(sourceComponent);
			
			if (LOG_TIME) {
				System.out.println(this.raAstStringCache.toString());
				System.out.println("RReconciler/createAST   : " + DecimalFormat.getInstance().format(stopAst - startAst)); //$NON-NLS-1$
			}
			
			synchronized (data.adapter) {
				data.adapter.setAst(data.ast);
			}
		}
	}
	
	protected final boolean updateModel(final Data data) {
		data.newModel= data.adapter.getCurrentModel();
		if (data.newModel != null && !data.ast.getStamp().equals(data.newModel.getStamp())) {
			data.newModel= null;
		}
		
		if (data.newModel == null) {
			final long startModel;
			final long stopModel;
			startModel= System.nanoTime();
			
			final RSourceUnitModelInfo model= this.rmScopeAnalyzer.createModel(data.adapter.getSourceUnit(), data.ast);
			final boolean isOK= (model != null);
			
			stopModel= System.nanoTime();
			
			if (LOG_TIME) {
				System.out.println("RReconciler/createMODEL : " + DecimalFormat.getInstance().format(stopModel - startModel)); 
			}
			
			if (isOK) {
				synchronized (data.adapter) {
					data.oldModel= data.adapter.getCurrentModel();
					data.adapter.setModel(model);
				}
				data.newModel= model;
				return true;
			}
		}
		return false;
	}
	
	private RSourceUnitModelInfo updateModel(final RSourceUnit su, final SourceUnitModelInfo modelInfo,
			final List<? extends RChunkElement> chunkElements,
			final List<? extends SourceComponent> inlineNodes) {
		RSourceUnitModelInfo model;
		try {
			final AstInfo ast= modelInfo.getAst();
			this.rmScopeAnalyzer.beginChunkSession(su, ast);
			for (final RChunkElement chunkElement : chunkElements) {
				final List<SourceComponent> rootNodes;
				{	final Object source= chunkElement.getAdapter(SourceComponent.class);
					if (source instanceof SourceComponent) {
						rootNodes= ImCollections.newList((SourceComponent) source);
					}
					else if (source instanceof List<?>) {
						rootNodes= (List<SourceComponent>) source;
					}
					else {
						continue;
					}
				}
				this.rmScopeAnalyzer.processChunk(chunkElement, rootNodes);
			}
			for (final SourceComponent inlineNode : inlineNodes) {
				final EmbeddedInlineElement inlineElement= new EmbeddedInlineElement(modelInfo.getSourceElement(), inlineNode);
				this.rmScopeAnalyzer.processInlineNode(inlineElement, inlineNode);
			}
		}
		finally {
			model= this.rmScopeAnalyzer.stopChunkSession();
		}
		return model;
	}
	
	void stop() {
		this.stop= true;
	}
	
}
