/*=============================================================================#
 # Copyright (c) 2008, 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.core.sourcemodel;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.text.core.BasicTextRegion;
import org.eclipse.statet.jcommons.text.core.TextRegion;

import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.model.core.LtkModelUtils;
import org.eclipse.statet.ltk.model.core.element.LtkModelElement;
import org.eclipse.statet.ltk.model.core.element.LtkModelElementFilter;
import org.eclipse.statet.r.core.model.ArgsDefinition;
import org.eclipse.statet.r.core.model.RElement;
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.RLangClass;
import org.eclipse.statet.r.core.model.RLangClassExtension;
import org.eclipse.statet.r.core.model.RLangMethod;
import org.eclipse.statet.r.core.model.RLangPackageLoad;
import org.eclipse.statet.r.core.model.RLangSlot;
import org.eclipse.statet.r.core.model.RLangSourceElement;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.model.RSourceUnit;
import org.eclipse.statet.r.core.rsource.ast.DocuComment;
import org.eclipse.statet.r.core.rsource.ast.FDef;
import org.eclipse.statet.r.core.rsource.ast.RAsts;


@NonNullByDefault
abstract class RSourceElementByElementAccess
		implements RLangSourceElement, LtkModelElementFilter<LtkModelElement<?>> {
	
	
	static final class RPkgImport extends RSourceElementByElementAccess implements RLangPackageLoad<RLangSourceElement> {
		
		
		public RPkgImport(final RLangSourceElement parent, final ElementAccess access) {
			super(parent, RElement.R_PACKAGE_LOAD, access);
		}
		
		
		@Override
		public @Nullable TextRegion getDocumentationRange() {
			return null;
		}
		
		
		@Override
		public boolean hasModelChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return false;
		}
		
		@Override
		public final List<? extends RLangSourceElement> getModelChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return RSourceModel.NO_R_SOURCE_CHILDREN;
		}
		
		@Override
		public boolean hasSourceChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return false;
		}
		
		@Override
		public List<? extends RLangSourceElement> getSourceChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return RSourceModel.NO_R_SOURCE_CHILDREN;
		}
		
	}
	
	static abstract class DocuCommentableElement extends RSourceElementByElementAccess {
		
		
		private @Nullable DocuComment docu;
		
		
		public DocuCommentableElement(final RLangSourceElement parent, final int elementType,
				final @Nullable ElementAccess defAccess) {
			super(parent, elementType, defAccess);
		}
		
		
		void setDocu(final DocuComment docu) {
			this.docu= docu;
		}
		
		@Override
		public final @Nullable DocuComment getDocumentationRange() {
			return this.docu;
		}
		
	}
	
	static abstract class DocuCommentableEnvirElement extends DocuCommentableElement
			implements BuildSourceFrameElement {
		
		private List<? extends RLangSourceElement> sourceChildrenProtected= RSourceModel.NO_R_SOURCE_CHILDREN;
		private @Nullable List<? extends RLangSourceElement> modelChildrenProtected;
		private final BuildSourceFrame envir;
		
		protected DocuCommentableEnvirElement(final RLangSourceElement parent, final BuildSourceFrame envir,
				final int elementType, final @Nullable ElementAccess defAccess) {
			super(parent, elementType, defAccess);
			this.envir= envir;
		}
		
		
		@Override
		public void setSourceChildren(final List<? extends RLangSourceElement> children) {
			this.sourceChildrenProtected= children;
		}
		
		@Override
		public BuildSourceFrame getBuildFrame() {
			return this.envir;
		}
		
		
		@Override
		public boolean hasModelChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			List<? extends RLangSourceElement> children= this.modelChildrenProtected;
			if (children == null) {
				children= this.envir.getModelChildren(this);
				this.modelChildrenProtected= children;
			}
			return LtkModelUtils.<RLangSourceElement>hasChildren(children, filter);
		}
		
		@Override
		public List<? extends RLangSourceElement> getModelChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			List<? extends RLangSourceElement> children= this.modelChildrenProtected;
			if (children == null) {
				children= this.envir.getModelChildren(this);
				this.modelChildrenProtected= children;
			}
			return LtkModelUtils.<RLangSourceElement>getChildren(children, filter);
		}
		
		@Override
		public boolean hasSourceChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return LtkModelUtils.<RLangSourceElement>hasChildren(this.sourceChildrenProtected, filter);
		}
		
		@Override
		public List<? extends RLangSourceElement> getSourceChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return LtkModelUtils.<RLangSourceElement>getChildren(this.sourceChildrenProtected, filter);
		}
		
		
		@Override
		@SuppressWarnings("unchecked")
		public <T> @Nullable T getAdapter(final Class<T> adapterType) {
			if (adapterType == RFrame.class) {
				return (T) this.envir;
			}
			return super.getAdapter(adapterType);
		}
		
	}
	
	static final class RMethod extends DocuCommentableEnvirElement implements RLangMethod<RLangSourceElement> {
		
		
		private final FDef fDefNode;
		private @Nullable ArgsDefinition args;
		
		
		public RMethod(final RLangSourceElement parent, final BuildSourceFrame envir, final FDef fdefNode) {
			super(parent, envir, RElement.R_COMMON_FUNCTION, null);
			this.fDefNode= fdefNode;
		}
		
		void complete(final int type, final ElementAccess defAccess, final @Nullable ArgsDefinition args) {
			this.type= type;
			setAccess(defAccess);
			this.args= args;
		}
		
		void complete(final AnonymousAccess defAccess, final ArgsDefinition args) {
			setAccess(defAccess);
			this.args= args;
		}
		
		
		public RMethod(final RLangSourceElement parent, final int type, final ElementAccess access, final BuildSourceFrame envir) {
			super(parent, envir, type, access);
			this.fDefNode= null;
		}
		
		public void complete(final ArgsDefinition args) {
			this.args= args;
		}
		
		
		public FDef getFDefNode() {
			return this.fDefNode;
		}
		
		@Override
		public @Nullable ArgsDefinition getArgsDefinition() {
			return this.args;
		}
		
		
		@Override
		@SuppressWarnings("unchecked")
		public <T> @Nullable T getAdapter(final Class<T> adapterType) {
			if (adapterType == FDef.class) {
				return (T) this.fDefNode;
			}
			return super.getAdapter(adapterType);
		}
		
	}
	
	static final class RClass extends DocuCommentableEnvirElement implements RLangClass<RLangSourceElement> {
		
		
		private static final List<String> NO_PARENTS= Collections.emptyList();
		
		
		private List<String> superClassesTypeNames= NO_PARENTS;
		private List<String> superClassesTypeNamesProtected= NO_PARENTS;
		
		
		public RClass(final RLangSourceElement parent, final ElementAccess defAccess, final BuildSourceFrame envir) {
			super(parent, envir, RElement.R_S4CLASS, defAccess);
		}
		
		public void addSuperClasses(final @Nullable String[] typeNames) {
			if (this.superClassesTypeNames == NO_PARENTS) {
				int count= 0;
				for (final String name : typeNames) {
					if (name != null) {
						count++;
					}
				}
				if (count == 0) {
					return;
				}
				this.superClassesTypeNames= new ArrayList<>(count);
				this.superClassesTypeNamesProtected= Collections.unmodifiableList(this.superClassesTypeNames);
			}
			for (final String name : typeNames) {
				if (name != null && !this.superClassesTypeNames.contains(name)) {
					this.superClassesTypeNames.add(name);
				}
			}
		}
		
		
		@Override
		public List<String> getExtendedClassNames() {
			return this.superClassesTypeNamesProtected;
		}
		
		
	}
	
	static final class RClassExt extends RSourceElementByElementAccess implements RLangClassExtension<RLangSourceElement>, BuildSourceFrameElement {
		
		
		private List<? extends RLangSourceElement> sourceChildrenProtected= RSourceModel.NO_R_SOURCE_CHILDREN;
		private @Nullable List<? extends RLangSourceElement> modelChildrenProtected;
		private final BuildSourceFrame envir;
		
		private final String extCommand;
		private @Nullable String extTypeName;
		
		
		public RClassExt(final RLangSourceElement parent, 
				final ElementAccess defAccess, final BuildSourceFrame envir, final String command) {
			super(parent, RElement.R_S4CLASS_EXTENSION, defAccess);
			this.envir= envir;
			this.extCommand= command;
		}
		
		public void complete(final @Nullable String extTypeName) {
			this.extTypeName= extTypeName;
		}
		
		@Override
		public void setSourceChildren(final List<? extends RLangSourceElement> children) {
			this.sourceChildrenProtected= children;
		}
		
		@Override
		public BuildSourceFrame getBuildFrame() {
			return this.envir;
		}
		
		
		@Override
		public String getExtCommand() {
			return this.extCommand;
		}
		
		@Override
		public @Nullable String getExtTypeName() {
			return this.extTypeName;
		}
		
		@Override
		public @Nullable TextRegion getDocumentationRange() {
			return null;
		}
		
		
		
		@Override
		public boolean hasModelChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			List<? extends RLangSourceElement> children= this.modelChildrenProtected;
			if (children == null) {
				children= this.envir.getModelChildren(this);
				this.modelChildrenProtected= children;
			}
			return LtkModelUtils.<RLangSourceElement>hasChildren(children, filter);
		}
		
		@Override
		public List<? extends RLangSourceElement> getModelChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			List<? extends RLangSourceElement> children= this.modelChildrenProtected;
			if (children == null) {
				children= this.envir.getModelChildren(this);
				this.modelChildrenProtected= children;
			}
			return LtkModelUtils.<RLangSourceElement>getChildren(children, filter);
		}
		
		@Override
		public boolean hasSourceChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return LtkModelUtils.<RLangSourceElement>hasChildren(this.sourceChildrenProtected, filter);
		}
		
		@Override
		public List<? extends RLangSourceElement> getSourceChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return LtkModelUtils.<RLangSourceElement>getChildren(this.sourceChildrenProtected, filter);
		}
		
		
		@Override
		@SuppressWarnings("unchecked")
		public <T> @Nullable T getAdapter(final Class<T> adapterType) {
			if (adapterType == RFrame.class) {
				return (T) this.envir;
			}
			return super.getAdapter(adapterType);
		}
		
	}
	
	static final class RVariable extends DocuCommentableElement {
		
		
		public RVariable(final RLangSourceElement parent, final int elementType, final ElementAccess defAccess) {
			super(parent, elementType, defAccess);
		}
		
		
		@Override
		public boolean hasModelChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return false;
		}
		
		@Override
		public final List<? extends RLangSourceElement> getModelChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return RSourceModel.NO_R_SOURCE_CHILDREN;
		}
		
		@Override
		public boolean hasSourceChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return false;
		}
		
		@Override
		public List<? extends RLangSourceElement> getSourceChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return RSourceModel.NO_R_SOURCE_CHILDREN;
		}
		
	}
	
	static final class RDataFrame extends DocuCommentableElement {
		
		
		private List<RElementAccess> columns;
		
		
		public RDataFrame(final RLangSourceElement parent, final int elementType,
				final List<SubNamedPartSyntacticElementAccess> columns) {
			super(parent, elementType, null);
		}
		
		
		@Override
		public boolean hasModelChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return false;
		}
		
		@Override
		public final List<? extends RLangSourceElement> getModelChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return RSourceModel.NO_R_SOURCE_CHILDREN;
		}
		
		@Override
		public boolean hasSourceChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return false;
		}
		
		@Override
		public List<? extends RLangSourceElement> getSourceChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return RSourceModel.NO_R_SOURCE_CHILDREN;
		}
		
	}
	
	static final class RSlot extends RSourceElementByElementAccess implements RLangSlot<RLangSourceElement> {
		
		
		private @Nullable String typeName;
		private String prototypeCode;
		
		
		public RSlot(final RLangSourceElement parent, final ElementAccess defAccess) {
			super(parent, RElement.R_S4SLOT, defAccess);
		}
		
		void completeType(final @Nullable String name) {
			this.typeName= name;
		}
		
		
		@Override
		public @Nullable String getTypeName() {
			return this.typeName;
		}
		
		@Override
		public @Nullable TextRegion getDocumentationRange() {
			return null;
		}
		
		
		@Override
		public boolean hasModelChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return false;
		}
		
		@Override
		public final List<? extends RLangSourceElement> getModelChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return RSourceModel.NO_R_SOURCE_CHILDREN;
		}
		
		@Override
		public boolean hasSourceChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return false;
		}
		
		@Override
		public List<? extends RLangSourceElement> getSourceChildren(final @Nullable LtkModelElementFilter<? super RLangSourceElement> filter) {
			return RSourceModel.NO_R_SOURCE_CHILDREN;
		}
		
	}
	
	
	private final RLangSourceElement parent;
	private RElementAccess access;
	int type;
	int occurrenceCount;
	
	
	public RSourceElementByElementAccess(final RLangSourceElement parent, final int elementType,
			final @Nullable ElementAccess defAccess) {
		this.parent= parent;
		this.type= elementType;
		setAccess(defAccess);
	}
	
	
	protected void setAccess(final @Nullable AnonymousAccess access) {
		if (access != null) {
			this.access= access;
		}
	}
	
	protected void setAccess(final @Nullable ElementAccess access) {
		if (access != null) {
			access.modelElement= this;
			this.access= access;
		}
	}
	
	@Override
	public final String getModelTypeId() {
		return RModel.R_TYPE_ID;
	}
	
	public final RElementAccess getAccess() {
		return this.access;
	}
	
	@Override
	public boolean include(final LtkModelElement<?> element) {
		return (element == this);
	}
	
	@Override
	public final @Nullable RElement<?> getModelParent() {
		final List<? extends RElement<?>> elements= this.access.getFrame().getModelElements();
		for (final RElement<?> element : elements) {
			if (element.hasModelChildren(this)) {
				return element;
			}
		}
		return null;
	}
	
	@Override
	public final RLangSourceElement getSourceParent() {
		return this.parent;
	}
	
	@Override
	public final RSourceUnit getSourceUnit() {
		return this.parent.getSourceUnit();
	}
	
	@Override
	public final int getElementType() {
		return this.type;
	}
	
	@Override
	public final RElementName getElementName() {
		return this.access;
	}
	
	@Override
	public final String getId() {
		final String name= getElementName().getDisplayName();
		final StringBuilder sb= new StringBuilder(name.length() + 10);
		sb.append(Integer.toHexString(this.type & MASK_C2));
		sb.append(':');
		sb.append(name);
		sb.append('#');
		sb.append(this.occurrenceCount);
		return sb.toString();
	}
	
	@Override
	public final boolean exists() {
		return this.parent.exists();
	}
	
	@Override
	public final boolean isReadOnly() {
		return this.parent.isReadOnly();
	}
	
	
	@Override
	public final TextRegion getSourceRange() {
		return this.access.getNode();
	}
	
	@Override
	public final TextRegion getNameSourceRange() {
		final RElementAccess access= this.access.getLastSegment();
		if (access.getNameNode() != null) {
			return RAsts.getElementNameRegion(access.getNameNode());
		}
		else {
			return new BasicTextRegion(access.getNode().getStartOffset());
		}
	}
	
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> @Nullable T getAdapter(final Class<T> adapterType) {
		if (adapterType == AstNode.class) {
			return (T) this.access.getNode();
		}
		if (adapterType == RElementAccess.class) {
			return (T) this.access;
		}
		return null;
	}
	
	
	@Override
	public int hashCode() {
		return (this.type & MASK_C2) * getElementName().hashCode() + this.occurrenceCount;
	}
	
	@Override
	public boolean equals(final @Nullable Object obj) {
		if (!(obj instanceof RSourceElementByElementAccess)) {
			return false;
		}
		final RSourceElementByElementAccess other= (RSourceElementByElementAccess) obj;
		return ((this.type & MASK_C2) == (other.type & MASK_C2))
				&& (this.occurrenceCount == other.occurrenceCount)
				&& ( ((this.type & MASK_C1) == C1_SOURCE) || (getSourceParent().equals(other.getSourceParent())) )
				&& (getElementName().equals(other.getElementName()));
	}
	
	
	@Override
	public String toString() {
		final StringBuilder sb= new StringBuilder(getClass().getSimpleName());
		sb.append(" (RSourceElementByElementAccess)"); //$NON-NLS-1$
		final RElementName elementName= getElementName();
		if (elementName != null) {
			sb.append(' ').append(elementName);
		}
		else {
			sb.append(" <unnamed>"); //$NON-NLS-1$
		}
		
		return sb.toString();
	}
	
}
