/*=============================================================================#
 # Copyright (c) 2014, 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.redocs.r.core.model;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;

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.string.InternStringCache;
import org.eclipse.statet.jcommons.text.core.BasicTextRegion;
import org.eclipse.statet.jcommons.text.core.TextLineInformation;
import org.eclipse.statet.jcommons.text.core.TextRegion;
import org.eclipse.statet.jcommons.text.core.input.StringParserInput;

import org.eclipse.statet.ltk.ast.core.AstInfo;
import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.ast.core.EmbeddingAstNode;
import org.eclipse.statet.ltk.core.SourceContent;
import org.eclipse.statet.ltk.issues.core.ProblemRequestor;
import org.eclipse.statet.ltk.model.core.build.EmbeddingForeignReconcileTask;
import org.eclipse.statet.ltk.model.core.build.SourceUnitModelContainer;
import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
import org.eclipse.statet.r.core.model.RCompositeSourceElement;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.model.RLangSourceElement;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.model.RModelManager;
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.rsource.ast.FCall.Arg;
import org.eclipse.statet.r.core.rsource.ast.FCall.Args;
import org.eclipse.statet.r.core.rsource.ast.NodeType;
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.SourceComponent;


@NonNullByDefault
public class RChunkReconciler<
		TSourceUnit extends RSourceUnit,
		TModelInfo extends SourceUnitModelInfo,
		TModelContainer extends SourceUnitModelContainer<TSourceUnit, TModelInfo>> {
	
	
	private final String name;
	
	private final RModelManager rManager;
	
	private final Matcher raChunkStartLineMatcher;
	private final @Nullable Matcher raChunkRefLineMatcher;
	private final Matcher raChunkEndLineMatcher;
	
	private final RParser raParser= new RParser(AstInfo.LEVEL_MODEL_DEFAULT, new InternStringCache(0x20));
	private final StringParserInput raInput= new StringParserInput(0x1000);
	
	protected final RProblemReporter rpReporter;
	
	
	public RChunkReconciler(final String name, final Pattern chunkStartLinePattern,
			final Pattern chunkRefLinePattern, final Pattern chunkEndLinePattern) {
		this.name= name;
		this.rManager= RModel.getRModelManager();
		
		this.raChunkStartLineMatcher= chunkStartLinePattern.matcher(""); //$NON-NLS-1$
		this.raChunkEndLineMatcher= chunkEndLinePattern.matcher(""); //$NON-NLS-1$
		this.raChunkRefLineMatcher= (chunkRefLinePattern != null) ? chunkRefLinePattern.matcher("") : null; //$NON-NLS-1$
		
		this.rpReporter= new RProblemReporter();
	}
	
	
	public String getName() {
		return this.name;
	}
	
	public RModelManager getRModelManager() {
		return this.rManager;
	}
	
	public void reconcileAst(final TModelContainer adapter,
			final SourceContent content, final List<? extends EmbeddingAstNode> list,
			final IProgressMonitor monitor) {
		final String source= content.getText();
		final TextLineInformation lines= content.getLines();
		
		this.raChunkStartLineMatcher.reset(source);
		if (this.raChunkRefLineMatcher != null) {
			this.raChunkRefLineMatcher.reset(source);
		}
		this.raChunkEndLineMatcher.reset(source);
		
		this.raInput.reset(source);
		
		for (final EmbeddingAstNode embeddingNode : list) {
			if (embeddingNode.getForeignTypeId() != RModel.R_TYPE_ID) {
				continue;
			}
			
			final RChunkNode rChunk= new RChunkNode(embeddingNode);
			rChunk.startOffset= embeddingNode.getStartOffset();
			rChunk.endOffset= embeddingNode.getEndOffset();
			embeddingNode.setForeignNode(rChunk);
			
			final IRegion startRegion;
			final List<IRegion> rCode= new ArrayList<>(4);
			
			switch ((embeddingNode.getEmbedDescr() & 0xf)) {
			
			case EmbeddingAstNode.EMBED_INLINE:
				startRegion= null;
				rCode.add(new Region(embeddingNode.getStartOffset(), embeddingNode.getLength()));
				break;
				
			case EmbeddingAstNode.EMBED_CHUNK: {
				int lineOffset= rChunk.startOffset;
				int line= lines.getLineOfOffset(rChunk.startOffset);
				int rCodeStartOffset;
				
				// start line
				int lineEndOffset= lines.getEndOffset(line);
				this.raChunkStartLineMatcher.region(lineOffset, lineEndOffset);
				if (!this.raChunkStartLineMatcher.matches()) {
					throw new IllegalStateException("R chunk does not start with start line.");
				}
				{	final int start= this.raChunkStartLineMatcher.start(1);
					final int end= this.raChunkStartLineMatcher.end(1);
					startRegion= new Region(start, end - start);
				}
				rCodeStartOffset= lineEndOffset;
				
				if (lineEndOffset < rChunk.endOffset) {
					do {
						line++;
						lineOffset= lineEndOffset;
						lineEndOffset= lines.getEndOffset(line);
						
						if (this.raChunkRefLineMatcher != null) {
							this.raChunkRefLineMatcher.region(lineOffset, lineEndOffset);
							if (this.raChunkRefLineMatcher.matches()) {
								if (rCodeStartOffset < lineOffset) {
									rCode.add(new Region(rCodeStartOffset, lineOffset - rCodeStartOffset));
								}
								rCodeStartOffset= lineEndOffset;
							}
						}
					} while (lineEndOffset < rChunk.endOffset);
					
					if (rChunk.endOffset != lineEndOffset) {
						throw new IllegalStateException("R chunk does not end at line end.");
					}
					
					this.raChunkEndLineMatcher.region(lineOffset, lineEndOffset);
					if (this.raChunkEndLineMatcher.matches()) {
						if (rCodeStartOffset < lineOffset) {
							rCode.add(new Region(rCodeStartOffset, lineOffset - rCodeStartOffset));
						}
						rCodeStartOffset= lineEndOffset;
					}
					else if (rCodeStartOffset < lineOffset) {
						rCode.add(new Region(rCodeStartOffset, lineEndOffset - rCodeStartOffset));
					}
				}
				break; }
			
			default:
				throw new UnsupportedOperationException("embedType= " + embeddingNode.getEmbedDescr());
			}
			
			if (startRegion != null) {
				rChunk.weaveArgs= this.raParser.scanFCallArgs(
						this.raInput.init(startRegion.getOffset(), startRegion.getOffset() + startRegion.getLength()),
						true );
			}
			final SourceComponent[] rCodeNodes= new @NonNull SourceComponent[rCode.size()];
			for (int j= 0; j < rCodeNodes.length; j++) {
				final IRegion region= rCode.get(j);
				rCodeNodes[j]= this.raParser.scanSourceRange(
						this.raInput.init(region.getOffset(), region.getOffset() + region.getLength()),
						rChunk, true );
			}
			rChunk.rSources= ImCollections.newList(rCodeNodes);
		}
	}
	
	public @Nullable RSourceUnitModelInfo reconcileModel(final TModelContainer adapter,
			final SourceContent content, final TModelInfo mainModel,
			final List<? extends EmbeddingForeignReconcileTask<?, ?>> list,
			final int level, final IProgressMonitor monitor) {
		if (list == null || list.isEmpty()) {
			return null;
		}
		
		int chunkCount= 0;
		final List<RedocsRChunkElement> chunkElements= new ArrayList<>();
		final List<SourceComponent> inlineNodes= new ArrayList<>();
		
		for (final EmbeddingForeignReconcileTask<?, ?> item : list) {
			if (item.getForeignTypeId() != RModel.R_TYPE_ID) {
				continue;
			}
			
			final EmbeddingAstNode embeddingNode= item.getAstNode();
			final RChunkNode rChunk= (RChunkNode) embeddingNode.getForeignNode();
			if (rChunk == null) {
				continue;
			}
			
			final ImList<SourceComponent> rSources= rChunk.getRCodeChildren();
			switch ((embeddingNode.getEmbedDescr() & 0xf)) {
			
			case EmbeddingAstNode.EMBED_INLINE:
				if (rSources.size() == 1) {
					inlineNodes.add(rSources.get(0));
				}
				break;
				
			case EmbeddingAstNode.EMBED_CHUNK: {
				chunkCount++;
				
				RElementName name= null;
				TextRegion nameRegion= null;
				{	final Arg labelArgNode= getLabelArgNode(rChunk.getWeaveArgsChild());
					if (labelArgNode != null && labelArgNode.hasValue()) {
						final RAstNode labelNode= labelArgNode.getValueChild();
						final String label;
						if (labelArgNode.getValueChild().getNodeType() == NodeType.SYMBOL) {
							label= labelNode.getText();
						}
						else {
							label= new String(content.getText().substring(
								labelNode.getStartOffset(), labelNode.getEndOffset() ));
						}
						name= RElementName.create(RElementName.MAIN_OTHER, label);
						nameRegion= labelNode;
					}
				}
				if (name == null) {
					name= RElementName.create(RElementName.MAIN_OTHER, "#"+Integer.toString(chunkCount)); //$NON-NLS-1$
					nameRegion= new BasicTextRegion(embeddingNode.getStartOffset() + 2);
				}
				final RedocsRChunkElement element= new RedocsRChunkElement(item.getEmbeddingElement(),
						rChunk, name, nameRegion );
				item.setEmbeddedElement(element);
				chunkElements.add(element);
				break; }
			}
		}
		
		if (chunkElements.isEmpty() && inlineNodes.isEmpty()) {
			return null;
		}
		
		final RSourceUnitModelInfo modelInfo= getRModelManager().reconcile(adapter.getSourceUnit(),
				mainModel, chunkElements, inlineNodes, level, monitor );
		mainModel.addAttachment(modelInfo);
		return modelInfo;
	}
	
	private @Nullable Arg getLabelArgNode(final @Nullable Args weaveArgs) {
		if (weaveArgs == null || !weaveArgs.hasChildren()) {
			return null;
		}
		for (int i= 0; i < weaveArgs.getChildCount(); i++) {
			final Arg arg= weaveArgs.getChild(i);
			if ((arg.hasName()) ?
					(arg.getNameChild().getNodeType() == NodeType.SYMBOL
							&& "label".equals(arg.getNameChild().getText()) ) : //$NON-NLS-1$
					(i == 0) ) {
				return arg;
			}
		}
		return null;
	}
	
	public void reportEmbeddedProblems(final TModelContainer adapter,
			final SourceContent content, final TModelInfo mainModel,
			final ProblemRequestor problemRequestor, final int level,
			final IProgressMonitor monitor) {
		final RSourceUnitModelInfo rModel= RModel.getRModelInfo(mainModel);
		if (rModel == null) {
			return;
		}
		final RSourceUnit su= adapter.getSourceUnit();
		final RLangSourceElement element= rModel.getSourceElement();
		if (element instanceof RCompositeSourceElement) {
			final List<? extends RLangSourceElement> elements= ((RCompositeSourceElement) element)
					.getCompositeElements();
			for (final RLangSourceElement rChunk : elements) {
				final AstNode rChunkNode= rChunk.getAdapter(AstNode.class);
				if (rChunkNode != null) {
					this.rpReporter.run(su, content, rChunkNode, problemRequestor);
				}
			}
		}
	}
	
}
