/*=============================================================================#
 # Copyright (c) 2009, 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.HashMap;

import org.eclipse.statet.internal.r.core.sourcemodel.RSourceElementByElementAccess.RClass;
import org.eclipse.statet.internal.r.core.sourcemodel.RSourceElementByElementAccess.RMethod;
import org.eclipse.statet.r.core.model.RElement;
import org.eclipse.statet.r.core.model.RLangSourceElement;
import org.eclipse.statet.r.core.model.RSourceFrame;
import org.eclipse.statet.r.core.rsource.ast.DocuTag;
import org.eclipse.statet.r.core.rsource.ast.NodeType;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;


/**
 * Describes how to handle special Roxygen tags
 */
public abstract class RoxygenTagType {
	
	
	public static final int INITIAL= 0x0;
	
	public static final int SCAN_MODE_FREETEXT= 0x0;
	public static final int SCAN_MODE_SYMBOL= 0x1;
	public static final int SCAN_MODE_RCODE= 0x2;
	
	public static final int FRAGMENT_ACTION_SELF_ACCESS= 0x1; 
	public static final int FRAGMENT_ACTION_PARAM_ACCESS= 0x2; 
	public static final int FRAGMENT_ACTION_SLOT_ACCESS= 0x3; 
	public static final int FRAGMENT_ACTION_PACKAGE_IMPORT= 0x4; 
	
	
	public static final HashMap<String, RoxygenTagType> TYPES= new HashMap<>();
	
	static {
		TYPES.put("param", new RoxygenTagType() {
			@Override
			public int getNextScanMode(final int previous) {
				if (previous == INITIAL) {
					return (0x100 | SCAN_MODE_SYMBOL);
				}
				return 0x900;
			}
			@Override
			public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) {
				if (element == null || (element.getElementType() & RElement.MASK_C1) != RElement.C1_METHOD) {
					return;
				}
				final int count= docuTag.getChildCount();
				if (count >= 1) {
					final RAstNode child= docuTag.getChild(0);
					if (child.getNodeType() == NodeType.SYMBOL) {
						context.createArgAccess(docuTag, (RMethod)element, child);
					}
				}
			}
		});
		TYPES.put("slot", new RoxygenTagType() {
			@Override
			public int getNextScanMode(final int previous) {
				if (previous == INITIAL) {
					return (0x100 | SCAN_MODE_SYMBOL);
				}
				return 0x900;
			}
			@Override
			public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) {
				if (element == null || (element.getElementType() & RElement.MASK_C1) != RElement.C1_CLASS) {
					return;
				}
				final int count= docuTag.getChildCount();
				if (count >= 1) {
					final RAstNode child= docuTag.getChild(0);
					if (child.getNodeType() == NodeType.SYMBOL) {
						context.createSlotAccess(docuTag, (RClass)element, child);
					}
				}
			}
		});
		TYPES.put("name", new RoxygenTagType() {
			@Override
			public int getNextScanMode(final int previous) {
				if (previous == INITIAL) {
					return (0x100 | SCAN_MODE_SYMBOL);
				}
				return 0x900;
			}
			@Override
			public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) {
				if (element == null) {
					return;
				}
				final int count= docuTag.getChildCount();
				if (count >= 1) {
					final RAstNode child= docuTag.getChild(0);
					if (child.getNodeType() == NodeType.SYMBOL) {
						context.createSelfAccess(docuTag, element, child);
					}
				}
			}
		});
		TYPES.put("aliases", new RoxygenTagType() {
			@Override
			public int getNextScanMode(final int previous) {
				return (0x100 | SCAN_MODE_SYMBOL);
			}
			@Override
			public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) {
				if (element == null) {
					return;
				}
				final int count= docuTag.getChildCount();
				for (int i= 0; i < count; i++) {
					final RAstNode child= docuTag.getChild(i);
					if (child.getNodeType() == NodeType.SYMBOL) {
						context.createSelfAccess(docuTag, element, child);
					}
				}
			}
		});
		TYPES.put("export", new RoxygenTagType() {
			@Override
			public int getNextScanMode(final int previous) {
				return (0x100 | SCAN_MODE_SYMBOL);
			}
			@Override
			public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) {
				if (element == null) {
					return;
				}
				final int count= docuTag.getChildCount();
				for (int i= 0; i < count; i++) {
					final RAstNode child= docuTag.getChild(i);
					if (child.getNodeType() == NodeType.SYMBOL) {
						context.createSelfAccess(docuTag, element, child);
					}
				}
			}
		});
		TYPES.put("exportClass", new RoxygenTagType() {
			@Override
			public int getNextScanMode(final int previous) {
				return (0x100 | SCAN_MODE_SYMBOL);
			}
			@Override
			public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) {
				if (element == null
						|| ((element.getElementType() & RElement.MASK_C1) != RElement.C1_CLASS
								&& (element.getElementType() & RElement.MASK_C1) != RElement.C1_VARIABLE) ) {
					return;
				}
				final int count= docuTag.getChildCount();
				for (int i= 0; i < count; i++) {
					final RAstNode child= docuTag.getChild(i);
					if (child.getNodeType() == NodeType.SYMBOL) {
						context.createSelfAccess(docuTag, element, child);
					}
				}
			}
		});
		TYPES.put("exportMethod", new RoxygenTagType() {
			@Override
			public int getNextScanMode(final int previous) {
				return (0x100 | SCAN_MODE_SYMBOL);
			}
			@Override
			public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) {
				if (element == null
						|| ((element.getElementType() & RElement.MASK_C1) != RElement.C1_METHOD
								&& (element.getElementType() & RElement.MASK_C1) != RElement.C1_VARIABLE) ) {
					return;
				}
				final int count= docuTag.getChildCount();
				for (int i= 0; i < count; i++) {
					final RAstNode child= docuTag.getChild(i);
					if (child.getNodeType() == NodeType.SYMBOL) {
						context.createSelfAccess(docuTag, element, child);
					}
				}
			}
		});
		TYPES.put("import", new RoxygenTagType() {
			@Override
			public int getNextScanMode(final int previous) {
				return (0x100 | SCAN_MODE_SYMBOL);
			}
			@Override
			public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) {
				final int count= docuTag.getChildCount();
				for (int i= 0; i < count; i++) {
					final RAstNode child= docuTag.getChild(i);
					if (child.getNodeType() == NodeType.SYMBOL) {
						context.createNamespaceImportAccess(docuTag, child);
					}
				}
			}
		});
		TYPES.put("importFrom", new RoxygenTagType() {
			@Override
			public int getNextScanMode(final int previous) {
				return (0x100 | SCAN_MODE_SYMBOL);
			}
			@Override
			public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) {
				final int count= docuTag.getChildCount();
				if (count >= 1) {
					RAstNode child= docuTag.getChild(0);
					if (child.getNodeType() == NodeType.SYMBOL) {
						context.createNamespaceImportAccess(docuTag, child);
					}
					final String name= child.getText();
					
					if (count >= 2 && name != null) {
						final RSourceFrame frame= context.getNamespaceFrame(name);
						if (frame != null) {
							for (int i= 1; i < count; i++) {
								child= docuTag.getChild(i);
								if (child.getNodeType() == NodeType.SYMBOL) {
									context.createNamespaceObjectImportAccess(docuTag, frame, child);
								}
							}
						}
					}
				}
			}
		});
		TYPES.put("importClassesFrom", new RoxygenTagType() {
			@Override
			public int getNextScanMode(final int previous) {
				return (0x100 | SCAN_MODE_SYMBOL);
			}
			@Override
			public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) {
				final int count= docuTag.getChildCount();
				if (count >= 1) {
					final RAstNode child= docuTag.getChild(0);
					if (child.getNodeType() == NodeType.SYMBOL) {
						context.createNamespaceImportAccess(docuTag, child);
					}
				}
			}
		});
		TYPES.put("importMethodsFrom", new RoxygenTagType() {
			@Override
			public int getNextScanMode(final int previous) {
				return (0x100 | SCAN_MODE_SYMBOL);
			}
			@Override
			public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) {
				final int count= docuTag.getChildCount();
				if (count >= 1) {
					final RAstNode child= docuTag.getChild(0);
					if (child.getNodeType() == NodeType.SYMBOL) {
						context.createNamespaceImportAccess(docuTag, child);
					}
				}
			}
		});
		TYPES.put("examples", new RoxygenTagType() {
			@Override
			public int getNextScanMode(final int previous) {
				return (0x100 | SCAN_MODE_RCODE);
			}
			@Override
			public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) {
				final int count= docuTag.getChildCount();
				if (count >= 1) {
					final RAstNode child= docuTag.getChild(0);
					if (child.getNodeType() == NodeType.SOURCELINES) {
						context.createRSourceRegion(child);
					}
				}
			}
		});
	}
	
	
	public RoxygenTagType() {
	}
	
	
	public abstract int getNextScanMode(int previous);
	
	public abstract void analyze(RoxygenAnalyzeContext context, DocuTag docuTag, RLangSourceElement element);
	
	
}
