/*=============================================================================#
 # Copyright (c) 2007, 2019 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.r.core.rsource.ast;

import static org.eclipse.statet.r.core.rsource.IRSourceConstants.STATUS2_SYNTAX_EXPR_AS_REF_MISSING;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.statet.jcommons.collections.IntArrayList;
import org.eclipse.statet.jcommons.collections.IntList;
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.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.ast.core.AstVisitor;
import org.eclipse.statet.r.core.rlang.RTerminal;


/**
 * <code>§ref§ ( §args§ )</code>
 */
@NonNullByDefault
public final class FCall extends RAstNode {
	
	
	public static final class Args extends RAstNode {
		
		
		final List<FCall.Arg> specs;
		final IntList sepList;
		
		
		Args(final FCall parent) {
			this.rParent= parent;
			this.specs= new ArrayList<>(1);
			this.sepList= new IntArrayList(1);
		}
		
//		Args(final List<FCall.Arg> args) {
//			rParent= null;
//			specs= args;
//		}
		
		
		@Override
		public final NodeType getNodeType() {
			return NodeType.F_CALL_ARGS;
		}
		
		@Override
		public final @Nullable RTerminal getOperator(final int index) {
			return null;
		}
		
		public int getSeparatorOffset(final int index) {
			return this.sepList.getAt(index);
		}
		
		@Override
		public final void acceptInR(final RAstVisitor visitor) throws InvocationTargetException {
			visitor.visit(this);
		}
		
		
		@Override
		public final boolean hasChildren() {
			return (!this.specs.isEmpty());
		}
		
		@Override
		public final int getChildCount() {
			return this.specs.size();
		}
		
		@Override
		public final FCall.Arg getChild(final int index) {
			return this.specs.get(index);
		}
		
		@Override
		public final FCall.Arg[] getChildren() {
			return this.specs.toArray(new FCall. @NonNull Arg[this.specs.size()]);
		}
		
		@Override
		public final int getChildIndex(final AstNode child) {
			for (int i= this.specs.size() - 1; i >= 0; i--) {
				if (this.specs.get(i) == child) {
					return i;
				}
			}
			return -1;
		}
		
		@Override
		public final void acceptInRChildren(final RAstVisitor visitor) throws InvocationTargetException {
			acceptChildren(visitor, this.specs);
		}
		
		@Override
		public final void acceptInChildren(final AstVisitor visitor) throws InvocationTargetException {
			for (final RAstNode child : this.specs) {
				visitor.visit(child);
			}
		}
		
		
		@Override
		final @Nullable Expression getExpr(final RAstNode child) {
			return null;
		}
		
		@Override
		final @Nullable Expression getLeftExpr() {
			return null;
		}
		
		@Override
		final @Nullable Expression getRightExpr() {
			return null;
		}
		
		
		@Override
		public final boolean equalsSingle(final RAstNode element) {
			return (element.getNodeType() == NodeType.F_CALL_ARGS);
		}
		
		@Override
		final int getMissingExprStatus(final Expression expr) {
			throw new IllegalArgumentException();
		}
		
		@Override
		final void updateEndOffset() {
		}
		
	}
	
	public static final class Arg extends SpecItem {
		
		
		Arg(final FCall.Args parent) {
			this.rParent= parent;
		}
		
		
		@Override
		public final NodeType getNodeType() {
			return NodeType.F_CALL_ARG;
		}
		
		@Override
		public final void acceptInR(final RAstVisitor visitor) throws InvocationTargetException {
			visitor.visit(this);
		}
		
		
		@Override
		public final boolean equalsSingle(final RAstNode element) {
			return (element.getNodeType() == NodeType.F_CALL_ARG);
		}
		
	}
	
	
	final Expression refExpr= new Expression();
	int argsOpenOffset= NA_OFFSET;
	final Args args= new Args(this);
	int argsCloseOffset= NA_OFFSET;
	
	
	FCall() {
	}
	
	
	@Override
	public final NodeType getNodeType() {
		return NodeType.F_CALL;
	}
	
	@Override
	public final @Nullable RTerminal getOperator(final int index) {
		return null;
	}
	
	
	@Override
	public final boolean hasChildren() {
		return true;
	}
	
	@Override
	public final int getChildCount() {
		return 2;
	}
	
	@Override
	public final RAstNode getChild(final int index) {
		switch (index) {
		case 0:
			return this.refExpr.node;
		case 1:
			return this.args;
		default:
			throw new IndexOutOfBoundsException();
		}
	}
	
	@Override
	public final RAstNode[] getChildren() {
		return new RAstNode[] { this.refExpr.node, this.args };
	}
	
	@Override
	public final int getChildIndex(final AstNode child) {
		if (this.refExpr.node == child) {
			return 0;
		}
		if (this.args == child) {
			return 1;
		}
		return -1;
	}
	
	public final RAstNode getRefChild() {
		return this.refExpr.node;
	}
	
	public final int getArgsOpenOffset() {
		return this.argsOpenOffset;
	}
	
	public final FCall.Args getArgsChild() {
		return this.args;
	}
	
	public final int getArgsCloseOffset() {
		return this.argsCloseOffset;
	}
	
	@Override
	public final void acceptInR(final RAstVisitor visitor) throws InvocationTargetException {
		visitor.visit(this);
	}
	
	@Override
	public final void acceptInRChildren(final RAstVisitor visitor) throws InvocationTargetException {
		this.refExpr.node.acceptInR(visitor);
		this.args.acceptInR(visitor);
	}
	
	@Override
	public final void acceptInChildren(final AstVisitor visitor) throws InvocationTargetException {
		visitor.visit(this.refExpr.node);
		visitor.visit(this.args);
	}
	
	
	@Override
	final @Nullable Expression getExpr(final RAstNode child) {
		if (this.refExpr.node == child) {
			return this.refExpr;
		}
		return null;
	}
	
	@Override
	final Expression getLeftExpr() {
		return this.refExpr;
	}
	
	@Override
	final @Nullable Expression getRightExpr() {
		return null;
	}
	
	@Override
	public final boolean equalsSingle(final RAstNode element) {
		if (element.getNodeType() != NodeType.F_CALL) {
			return false;
		}
		final RAstNode otherExprNode= ((FCall) element).refExpr.node;
		return ((this.refExpr.node == otherExprNode
				|| this.refExpr.node != null && this.refExpr.node.equalsSingle(otherExprNode)) );
	}
	
	
	@Override
	final int getMissingExprStatus(final Expression expr) {
		if (expr == this.refExpr) {
			return STATUS2_SYNTAX_EXPR_AS_REF_MISSING;
		}
		throw new IllegalArgumentException();
	}
	
	final void updateStartOffset() {
		this.startOffset= this.refExpr.node.startOffset;
	}
	
	@Override
	final void updateEndOffset() {
		if (this.argsCloseOffset != NA_OFFSET) {
			this.endOffset= this.argsCloseOffset + 1;
		}
		else {
			this.endOffset= this.args.endOffset;
		}
	}
	
}
