/*******************************************************************************
 * Copyright (c) 2016, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.parser;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.ExportsStatement;
import org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ModuleStatement;
import org.eclipse.jdt.internal.compiler.ast.OpensStatement;
import org.eclipse.jdt.internal.compiler.ast.ProvidesStatement;
import org.eclipse.jdt.internal.compiler.ast.RequiresStatement;
import org.eclipse.jdt.internal.compiler.ast.UsesStatement;

public class RecoveredModule extends RecoveredElement {
	
	public RecoveredExportsStatement[] exports;
	public int exportCount;
	public RecoveredOpensStatement[] opens;
	public int opensCount;
	public RecoveredRequiresStatement[] requires;
	public int requiresCount;
	public RecoveredUsesStatement[] uses;
	public int usesCount;
	public RecoveredProvidesStatement[] services;
	public int servicesCount;
	public ModuleDeclaration moduleDeclaration;

	public RecoveredModule(ModuleDeclaration moduleDeclaration, RecoveredElement parent, int bracketBalance) {
		super(parent, bracketBalance);
		this.moduleDeclaration = moduleDeclaration;
	}
	@Override
	public RecoveredElement add(ModuleStatement moduleStatement, int bracketBalanceValue) {
		
		// TODO: can't we do away with all these additions except for ProvidesStatement - to check
		// if there are any corner cases that uses these.
		if (moduleStatement instanceof ExportsStatement) {
			return add((ExportsStatement) moduleStatement, bracketBalanceValue);
		}
		if (moduleStatement instanceof OpensStatement) {
			return add((OpensStatement) moduleStatement, bracketBalanceValue);
		}
		if (moduleStatement instanceof RequiresStatement) {
			return add((RequiresStatement) moduleStatement, bracketBalanceValue);
		}
		if (moduleStatement instanceof ProvidesStatement) {
			return add((ProvidesStatement) moduleStatement, bracketBalanceValue);
		}
		if (moduleStatement instanceof UsesStatement) {
			return add((UsesStatement) moduleStatement, bracketBalanceValue);
		}
		
		return this;
	}

	public RecoveredElement add(ExportsStatement exportsStatement, int bracketBalanceValue) {
		resetPendingModifiers();

		if (this.exports == null) {
			this.exports = new RecoveredExportsStatement[5];
			this.exportCount = 0;
		} else {
			if (this.exportCount == this.exports.length) {
				System.arraycopy(
					this.exports,
					0,
					(this.exports = new RecoveredExportsStatement[2 * this.exportCount]),
					0,
					this.exportCount);
			}
		}
		RecoveredExportsStatement element = new RecoveredExportsStatement(exportsStatement, this, bracketBalanceValue);
		this.exports[this.exportCount++] = element;

		return element;
	}
	public RecoveredElement add(OpensStatement opensStatement, int bracketBalanceValue) {
		resetPendingModifiers();

		if (this.opens == null) {
			this.opens = new RecoveredOpensStatement[5];
			this.opensCount = 0;
		} else {
			if (this.opensCount == this.opens.length) {
				System.arraycopy(
					this.opens,
					0,
					(this.opens = new RecoveredOpensStatement[2 * this.opensCount]),
					0,
					this.opensCount);
			}
		}
		RecoveredOpensStatement element = new RecoveredOpensStatement(opensStatement, this, bracketBalanceValue);
		this.opens[this.opensCount++] = element;

		return element;
	}
	public RecoveredElement add(RequiresStatement requiresStatement, int bracketBalanceValue) {
		if (this.requires == null) {
			this.requires = new RecoveredRequiresStatement[5];
			this.requiresCount = 0;
		} else {
			if (this.requiresCount == this.requires.length) {
				System.arraycopy(
					this.requires,
					0,
					(this.requires = new RecoveredRequiresStatement[2 * this.requiresCount]),
					0,
					this.requiresCount);
			}
		}
		RecoveredRequiresStatement element = new RecoveredRequiresStatement(requiresStatement, this, bracketBalanceValue);
		this.requires[this.requiresCount++] = element;
		return this;
	}
	public RecoveredElement add(ProvidesStatement providesStatement, int bracketBalanceValue) {
		if (this.services == null) {
			this.services = new RecoveredProvidesStatement[5];
			this.servicesCount = 0;
		} else {
			if (this.servicesCount == this.services.length) {
				System.arraycopy(
					this.services,
					0,
					(this.services = new RecoveredProvidesStatement[2 * this.servicesCount]),
					0,
					this.servicesCount);
			}
		}
		RecoveredProvidesStatement element = new RecoveredProvidesStatement(providesStatement, this, bracketBalanceValue);
		this.services[this.servicesCount++] = element;
		return element;
	}
	public RecoveredElement add(UsesStatement usesStatement, int bracketBalanceValue) {
		genAssign(usesStatement, bracketBalanceValue);
		return this;
	}
	private void genAssign(UsesStatement usesStatement, int bracketBalanceValue) {
		if (this.uses == null) {
			this.uses = new RecoveredUsesStatement[5];
			this.usesCount = 0;
		} else {
			if (this.usesCount == this.uses.length) {
				System.arraycopy(
					this.uses,
					0,
					(this.uses = new RecoveredUsesStatement[2 * this.usesCount]),
					0,
					this.usesCount);
			}
		}
		RecoveredUsesStatement element = new RecoveredUsesStatement(usesStatement, this, bracketBalanceValue);
		this.uses[this.usesCount++] = element;
	}
	@Override
	public String toString(int tab) {
		StringBuffer result = new StringBuffer(tabString(tab));
		result.append("Recovered module:\n"); //$NON-NLS-1$
		result.append("module ");//$NON-NLS-1$
		result.append(CharOperation.charToString(this.moduleDeclaration.moduleName));
		result.append(" {");//$NON-NLS-1$
		if (this.exportCount > 0) {
			for (int i = 0; i < this.exportCount; ++i) {
				result.append("\n"); //$NON-NLS-1$
				result.append(this.exports[i].toString(tab + 1));
			}
		}
		if (this.requiresCount > 0) {
			for (int i = 0; i < this.requiresCount; ++i) {
				result.append("\n"); //$NON-NLS-1$
				result.append(this.requires[i].toString(tab + 1));
			}
		}
		if (this.usesCount > 0) {
			for (int i = 0; i < this.usesCount; ++i) {
				result.append("\n"); //$NON-NLS-1$
				result.append(this.uses[i].toString(tab + 1));
			}
		}
		if (this.servicesCount > 0) {
			for (int i = 0; i < this.servicesCount; ++i) {
				result.append("\n"); //$NON-NLS-1$
				result.append(this.services[i].toString(tab + 1));
			}
		}
		result.append("\n}");//$NON-NLS-1$
		return result.toString();
	}
	public ModuleDeclaration updatedModuleDeclaration() {

		updateExports(this.moduleDeclaration);
		updateOpens(this.moduleDeclaration);
		updateRequires(this.moduleDeclaration);
		updateUses(this.moduleDeclaration);
		updateServices(this.moduleDeclaration);
		return this.moduleDeclaration;
	}
	private void updateExports(ModuleDeclaration mod) {
		if (this.exportCount > 0) {
			int existingCount = mod.exportsCount, actualCount = 0;
			ExportsStatement[] exports1 = new ExportsStatement[existingCount + this.exportCount];
			if (existingCount > 0){
				System.arraycopy(mod.exports, 0, exports1, 0, existingCount);
				actualCount = existingCount;
			}
			for (int i = 0; i < this.exportCount; i++){
				exports1[actualCount++] = (ExportsStatement)this.exports[i].updatedPackageVisibilityStatement();
			}
			mod.exports = exports1;
			mod.exportsCount = actualCount;
		}
	}
	private void updateOpens(ModuleDeclaration mod) {
		if (this.opensCount > 0) {
			int existingCount = mod.opensCount, actualCount = 0;
			OpensStatement[] opens1 = new OpensStatement[existingCount + this.opensCount];
			if (existingCount > 0){
				System.arraycopy(mod.exports, 0, opens1, 0, existingCount);
				actualCount = existingCount;
			}
			for (int i = 0; i < this.opensCount; i++){
				opens1[actualCount++] = (OpensStatement)this.opens[i].updatedPackageVisibilityStatement();
			}
			mod.opens = opens1;
			mod.opensCount = actualCount;
		}
	}
	private void updateRequires(ModuleDeclaration mod) {
		if (this.requiresCount > 0) {
			int existingCount = mod.requiresCount, actualCount = 0;
			RequiresStatement[] requiresStmts = new RequiresStatement[existingCount + this.requiresCount];
			if (existingCount > 0){
				System.arraycopy(mod.requires, 0, requiresStmts, 0, existingCount);
				actualCount = existingCount;
			}
			for (int i = 0; i < this.requiresCount; i++){
				requiresStmts[actualCount++] = this.requires[i].updatedRequiresStatement();
			}
			mod.requires = requiresStmts;
			mod.requiresCount = actualCount;
		}
	}
	private void updateUses(ModuleDeclaration mod) {
		if (this.usesCount > 0) {
			int existingCount = mod.usesCount, actualCount = 0;
			UsesStatement[] usesStmts = new UsesStatement[existingCount + this.usesCount];
			if (existingCount > 0){
				System.arraycopy(mod.uses, 0, usesStmts, 0, existingCount);
				actualCount = existingCount;
			}
			for (int i = 0; i < this.usesCount; ++i) {
				usesStmts[actualCount++] = this.uses[i].updatedUsesStatement();
			}
			mod.uses = usesStmts;
			mod.usesCount = actualCount;
		}
	}
	private void updateServices(ModuleDeclaration mod) {
		if (this.servicesCount > 0) {
			int existingCount = mod.servicesCount, actualCount = 0;
			ProvidesStatement[] providesStmts = new ProvidesStatement[existingCount + this.servicesCount];
			if (existingCount > 0){
				System.arraycopy(mod.services, 0, providesStmts, 0, existingCount);
				actualCount = existingCount;
			}
			for (int i = 0; i < this.servicesCount; ++i) {
				providesStmts[actualCount++] = this.services[i].updatedProvidesStatement();
			}
			mod.services = providesStmts;
			mod.servicesCount = actualCount;  			
		}
	}
	@Override
	public void updateParseTree(){
		updatedModuleDeclaration();
	}

}
