/*=============================================================================#
 # 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.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.RModelUtils;
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;


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 TextRegion region= RModelUtils.getNameSourceRegion(access);
						
						final Integer lineNumber= Integer.valueOf(
								lineInformation.getLineOfOffset(region.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,
								region.getStartOffset(), region.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();
	}
	
}
