/*=============================================================================#
 # Copyright (c) 2014, 2020 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.ui.search;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.text.BadLocationException;

import org.eclipse.statet.jcommons.text.core.TextLineInformation;
import org.eclipse.statet.jcommons.text.core.TextRegion;

import org.eclipse.statet.ecommons.workbench.search.ui.LineElement;

import org.eclipse.statet.ltk.core.SourceContent;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;
import org.eclipse.statet.r.core.RProject;
import org.eclipse.statet.r.core.model.RElementAccess;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.model.RFrame;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.model.RModelManager;
import org.eclipse.statet.r.core.model.RSourceFrame;
import org.eclipse.statet.r.core.model.RSourceUnit;
import org.eclipse.statet.r.core.model.RSourceUnitModelInfo;
import org.eclipse.statet.r.core.refactoring.RElementSearchProcessor;
import org.eclipse.statet.r.core.rsource.ast.RAsts;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;


public class RElementSearch extends RElementSearchProcessor {
	
	
	private final boolean searchWrite;
	
	RElementSearchResult result;
	
	private final StringBuilder sb= new StringBuilder();
	
	
	public RElementSearch(final RElementName name,
			final RSourceUnit sourceUnit, final RElementAccess mainAccess,
			final Mode mode, final boolean searchWrite) {
		super(name, sourceUnit, mainAccess, mode, ALLOW_SUB_NAMEDPART);
		
		this.searchWrite= searchWrite;
	}
	
	
	public final boolean searchWrite() {
		return this.searchWrite;
	}
	
	@Override
	protected void begin(final SubMonitor progress) {
		super.begin(progress);
		
		this.result.removeAll();
	}
	
	@Override
	protected void process(final RProject project, final List<SourceUnit> sus,
			final SubMonitor progress) throws BadLocationException {
		if (sus != null) {
			int remaining= sus.size();
			for (final SourceUnit su : sus) {
				progress.setWorkRemaining(remaining--);
				
				process((RSourceUnit)su, progress.newChild(1));
			}
		}
	}
	
	protected void process(final RSourceUnit sourceUnit, final SubMonitor progress) throws BadLocationException {
		progress.setWorkRemaining(10);
		sourceUnit.connect(progress.newChild(1));
		try {
			RSourceUnit bestUnit= sourceUnit;
			if (bestUnit.getUnderlyingUnit() != null && bestUnit.isSynchronized()) {
				bestUnit= sourceUnit;
			}
			
			final RSourceUnitModelInfo modelInfo= (RSourceUnitModelInfo)sourceUnit.getModelInfo(RModel.R_TYPE_ID,
					RModelManager.MODEL_FILE, progress.newChild(1) );
			final SourceContent content= sourceUnit.getContent(progress.newChild(1));
			
			final List<List<? extends RElementAccess>> allFrameAccess= new ArrayList<>();
			for (final String frameId : this.definitionFrameIds) {
				final RFrame frame;
				if (frameId == null) {
					frame= modelInfo.getTopFrame();
				}
				else {
					frame= modelInfo.getReferencedFrames().get(frameId);
				}
				if (frame instanceof RSourceFrame) {
					final List<? extends RElementAccess> allAccess= ((RSourceFrame)frame).getAllAccessOf(
							this.mainName.getSegmentName(), true );
					if (allAccess != null && allAccess.size() > 0) {
						allFrameAccess.add(allAccess);
					}
				}
			}
			
			final String contentText= content.getText();
			final TextLineInformation lineInformation= content.getLines();
			final Map<Integer, LineElement<RSourceUnit>> lineElements= new HashMap<>();
			
			for (final List<? extends RElementAccess> allAccess : allFrameAccess) {
				for (RElementAccess access : allAccess) {
					access= include(access);
					if (access != null) {
						final RAstNode nameNode= access.getNameNode();
						final TextRegion nameRegion= RAsts.getElementNameRegion(nameNode);
						
						final Integer lineNumber= Integer.valueOf(
								lineInformation.getLineOfOffset(nameRegion.getStartOffset()) );
						LineElement<RSourceUnit> lineElement= lineElements.get(lineNumber);
						if (lineElement == null) {
							final int lineOffset= lineInformation.getStartOffset(lineNumber);
							lineElement= new LineElement<>(bestUnit, lineNumber, lineOffset,
									getContent(contentText, lineOffset, lineOffset + lineInformation.getLength(lineNumber)) );
							lineElements.put(lineNumber, lineElement);
						}
						
						this.result.addMatch(new RElementMatch(lineElement,
								nameRegion.getStartOffset(), nameRegion.getLength(),
								(access.isWriteAccess() && access.getNextSegment() == null) ));
					}
				}
			}
			progress.setWorkRemaining(1);
		}
		finally {
			sourceUnit.disconnect(progress.newChild(1));
		}
	}
	
	private RElementAccess include(RElementAccess access) {
		access= searchMatch(access);
		return (access != null && access.isMaster()
						&& (!searchWrite() || access.isWriteAccess()) ) ?
				access : null;
	}
	
	private String getContent(final String text, final int start, final int end) {
		this.sb.setLength(0);
		for (int idx= start; idx < end; idx++) {
			final char c= text.charAt(idx);
			if (Character.isWhitespace(c) || Character.isISOControl(c)) {
				this.sb.append(' ');
			} else {
				this.sb.append(c);
			}
		}
		return this.sb.toString();
	}
	
}
