/*=============================================================================#
 # Copyright (c) 2019 Stephan Wahlbrink <sw@wahlbrink.eu> 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.rj.servi.pool;

import static org.junit.Assert.assertEquals;

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

import org.junit.Assume;
import org.junit.BeforeClass;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.status.StatusException;

import org.eclipse.statet.rj.data.RDataUtils;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.UnexpectedRDataException;
import org.eclipse.statet.rj.servi.RServi;


@NonNullByDefault
public class AbstractServiTest {
	
	
	@BeforeClass
	public static void checkR() {
		Assume.assumeTrue(System.getenv("R_HOME") != null);
	}
	
	
	private final List<RServi> servis= new ArrayList<>();
	
	private int testInt;
	
	
	public AbstractServiTest() {
		ServiTests.initEnv();
	}
	
	
	protected void disposeServis(final List<Throwable> exceptions) {
		try {
			for (final RServi servi : this.servis) {
				try {
					servi.close();
				}
				catch (final Throwable e) {
					exceptions.add(e);
				}
			}
		}
		finally {
			this.servis.clear();
		}
	}
	
	protected void onServiGet(final RServi servi) {
		this.servis.add(servi);
	}
	
	protected void closeServi(final RServi servi) throws StatusException {
		this.servis.remove(servi);
		servi.close();
	}
	
	
	protected void assertNodeOperative(final RServi servi) throws StatusException, UnexpectedRDataException {
		final int i= this.testInt++;
		final RObject result= servi.evalData(i + "L + 1L", null);
		assertEquals(i + 1, RDataUtils.checkSingleIntValue(result));
	}
	
}
