/*=============================================================================#
 # 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 sourceContent, final List<? extends EmbeddingAstNode> list,
			final IProgressMonitor monitor) {
		if (sourceContent.getStartOffset() != 0) {
			throw new UnsupportedOperationException();
		}
		
		final String source= sourceContent.getString();
		final TextLineInformation lines= sourceContent.getStringLines();
		
		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= content.getString(
									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);
				}
			}
		}
	}
	
}
