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

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

import java.lang.reflect.InvocationTargetException;

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;


/**
 * 
 */
@NonNullByDefault
abstract class SpecItem extends RAstNode {
	
	
	@Nullable RAstNode argName;
	int equalsOffset= NA_OFFSET;
	final Expression valueExpr= new Expression();
	
	
	protected SpecItem() {
	}
	
	
	@Override
	public final @Nullable RTerminal getOperator(final int index) {
		return null;
	}
	
	public final int getAssignOffset() {
		return this.equalsOffset;
	}
	
	
	@Override
	public final boolean hasChildren() {
		return (this.argName != null || this.valueExpr.node != null);
	}
	
	@Override
	public final int getChildCount() {
		int count= (this.argName != null) ? 1 : 0;
		if (this.valueExpr.node != null) {
			count++;
		}
		return count;
	}
	
	public final boolean hasName() {
		return (this.argName != null);
	}
	
	public final @Nullable RAstNode getNameChild() {
		return this.argName;
	}
	
	public boolean hasValue() {
		return (this.valueExpr.node != null);
	}
	
	public final @Nullable RAstNode getValueChild() {
		return this.valueExpr.node;
	}
	
	@Override
	public final RAstNode getChild(final int index) {
		final RAstNode nameNode= this.argName;
		final RAstNode valueNode= this.valueExpr.node;
		if (nameNode != null) {
			switch (index) {
			case 0:
				return nameNode;
			case 1:
				if (valueNode != null) {
					return valueNode;
				}
				//$FALL-THROUGH$
			default:
				throw new IndexOutOfBoundsException();
			}
		}
		else {
			switch (index) {
			case 0:
				if (valueNode != null) {
					return valueNode;
				}
				//$FALL-THROUGH$
			default:
				throw new IndexOutOfBoundsException();
			}
		}
	}
	
	@Override
	public final RAstNode[] getChildren() {
		final RAstNode nameNode= this.argName;
		final RAstNode valueNode= this.valueExpr.node;
		if (nameNode != null) {
			if (valueNode != null) {
				return new RAstNode[] { nameNode, valueNode };
			}
			else {
				return new RAstNode[] { nameNode };
			}
		}
		else if (valueNode != null) {
			return new RAstNode[] { valueNode };
		}
		else {
			return NO_CHILDREN;
		}
	}
	
	@Override
	public int getChildIndex(final AstNode child) {
		if (this.argName == child) {
			return 0;
		}
		if (this.valueExpr.node == child) {
			return 1;
		}
		return -1;
	}
	
	@Override
	public final void acceptInRChildren(final RAstVisitor visitor) throws InvocationTargetException {
		final RAstNode nameNode= this.argName;
		final RAstNode valueNode= this.valueExpr.node;
		if (nameNode != null) {
			nameNode.acceptInR(visitor);
		}
		if (valueNode != null) {
			valueNode.acceptInR(visitor);
		}
	}
	
	@Override
	public final void acceptInChildren(final AstVisitor visitor) throws InvocationTargetException {
		final RAstNode nameNode= this.argName;
		final RAstNode valueNode= this.valueExpr.node;
		if (nameNode != null) {
			visitor.visit(nameNode);
		}
		if (valueNode != null) {
			visitor.visit(valueNode);
		}
	}
	
	
	@Override
	final @Nullable Expression getExpr(final RAstNode child) {
		if (this.valueExpr.node == child) {
			return this.valueExpr;
		}
		return null;
	}
	
	@Override
	final @Nullable Expression getLeftExpr() {
		return null;
	}
	
	@Override
	final Expression getRightExpr() {
		return this.valueExpr;
	}
	
	
	@Override
	final int getMissingExprStatus(final Expression expr) {
		if (this.valueExpr == expr) {
			return STATUS_OK;
		}
		throw new IllegalArgumentException();
	}
	
	@Override
	@SuppressWarnings({ "null", "unused" })
	final void updateEndOffset() {
		if (this.valueExpr.node != null) {
			this.endOffset= this.valueExpr.node.endOffset;
		}
		else if (this.equalsOffset != NA_OFFSET) {
			this.endOffset= this.equalsOffset+1;
		}
		else if (this.argName != null) {
			this.endOffset= this.argName.endOffset;
		}
		else {
			this.endOffset= this.startOffset;
		}
	}
	
}
