package com.sixsq.slipstream.stats;

/*
 * +=================================================================+
 * SlipStream Server (WAR)
 * =====
 * Copyright (C) 2013 SixSq Sarl (sixsq.com)
 * =====
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * -=================================================================-
 */

import static org.junit.Assert.assertEquals;

import java.lang.reflect.InvocationTargetException;

import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;

import com.sixsq.slipstream.common.util.CommonTestUtil;
import com.sixsq.slipstream.connector.ParametersFactory;
import com.sixsq.slipstream.exceptions.ConfigurationException;
import com.sixsq.slipstream.exceptions.NotFoundException;
import com.sixsq.slipstream.exceptions.SlipStreamException;
import com.sixsq.slipstream.exceptions.ValidationException;
import com.sixsq.slipstream.persistence.CloudImageIdentifier;
import com.sixsq.slipstream.persistence.ImageModule;
import com.sixsq.slipstream.persistence.Module;
import com.sixsq.slipstream.persistence.ModuleParameter;
import com.sixsq.slipstream.persistence.Run;
import com.sixsq.slipstream.persistence.RunType;
import com.sixsq.slipstream.run.RunTestBase;

public class MeasurementsTest extends RunTestBase {

	@BeforeClass
	public static void setupClass() throws InstantiationException,
			IllegalAccessException, InvocationTargetException,
			NoSuchMethodException, ClassNotFoundException,
			ConfigurationException, ValidationException, NotFoundException {

		CommonTestUtil
				.resetAndLoadConnector(com.sixsq.slipstream.connector.local.LocalConnector.class);

		setupImages();

		imagebuildme = updateImageForLocalConnector(imagebuildme, 2, 4);
		image = updateImageForLocalConnector(image, 22, 44);

		setupDeployments();
		imageForDeployment1 = updateImageForDeployment(imageForDeployment1, 4,
				8);
		imageForDeployment1 = imageForDeployment1.store();
		imageForDeployment2 = updateImageForDeployment(imageForDeployment2, 44,
				88);
		imageForDeployment2 = imageForDeployment2.store();

		createUser();
	}

	private static ImageModule updateImageForLocalConnector(ImageModule image,
			int cpu, int ram) throws ValidationException {
		image.setParameter(new ModuleParameter(ParametersFactory.constructKey(
				cloudServiceName, Run.CPU_PARAMETER_NAME), String.valueOf(cpu),
				""));
		image.setParameter(new ModuleParameter(ParametersFactory.constructKey(
				cloudServiceName, Run.RAM_PARAMETER_NAME), String.valueOf(ram),
				""));

		return image.store();
	}

	private static ImageModule updateImageForDeployment(ImageModule image,
			int cpu, int ram) throws ValidationException {
		image = updateImageForLocalConnector(image, cpu, ram);
		image.getCloudImageIdentifiers().add(
				new CloudImageIdentifier(image, cloudServiceName, "abc"));
		return image.store();
	}

	@After
	public void tearDown() throws ConfigurationException, ValidationException {

		for (Run r : Run.viewListAllActive()) {
			r.remove();
		}

	}

	@Test
	public void computeImageBuildRun() throws SlipStreamException {

		createACoupleOfImageBuildRuns(imagebuildme);

		Measurements ms = new Measurements();
		ms.populate(user);

		assertEquals(4, ms.getMeasurments().size());

		// first orchestrator
		Measurement m = ms.getMeasurments().get(0);

		assertEquals(1, m.getCpu());
		assertEquals(1, m.getRam());

		// first machine
		m = ms.getMeasurments().get(1);

		assertEquals(2, m.getCpu());
		assertEquals(4, m.getRam());

		// second machine
		m = ms.getMeasurments().get(3);

		assertEquals(2, m.getCpu());
		assertEquals(4, m.getRam());
	}

	@Test
	public void computeDeploymentRun() throws SlipStreamException {

		createACoupleOfDeploymentRuns(deployment);

		Measurements ms = new Measurements();
		ms.populate(user);

		// 2 x (2 VMs + 1 orchestrator)
		assertEquals(6, ms.getMeasurments().size());

		Measurement m = ms.getMeasurments().get(0);

		assertEquals(1, m.getCpu());
		assertEquals(1, m.getRam());

		m = ms.getMeasurments().get(1);

		assertEquals(4, m.getCpu());
		assertEquals(8, m.getRam());

		m = ms.getMeasurments().get(2);

		assertEquals(44, m.getCpu());
		assertEquals(88, m.getRam());
	}

	@Test
	public void computeSimpleRun() throws SlipStreamException {

		createACoupleOfSimpleRuns(image);

		Measurements ms = new Measurements();
		ms.populate(user);

		assertEquals(2, ms.getMeasurments().size());

		Measurement m = ms.getMeasurments().get(1);

		assertEquals(22, m.getCpu());
		assertEquals(44, m.getRam());
	}

	private void createACoupleOfImageBuildRuns(Module module)
			throws SlipStreamException {
		createAndStoreRun(module, user.getName(), RunType.Machine);
		createAndStoreRun(module, user.getName(), RunType.Machine);
	}

	private void createACoupleOfDeploymentRuns(Module module)
			throws SlipStreamException {
		createAndStoreRun(module, user.getName(), RunType.Orchestration);
		createAndStoreRun(module, user.getName(), RunType.Orchestration);
	}

	private void createACoupleOfSimpleRuns(Module module)
			throws SlipStreamException {
		createAndStoreRun(module, user.getName(), RunType.Run);
		createAndStoreRun(module, user.getName(), RunType.Run);
	}

}

@@ -2574,24 +2574,211 @@
 eateUser();%0A
+%09%09%0A%09%09removeRuns();%0A%09%09%0A%09%09CommonTestUtil.createDeployment();%0A%09%7D%0A%0A%09private static void removeRuns() throws ValidationException %7B%0A%09%09for (Run r : Run.viewListAllActive()) %7B%0A%09%09%09r.remove();%0A%09%09%7D%0A
 %09%7D%0A%0A%09private
@@ -3628,66 +3628,21 @@
 %0A%0A%09%09
-for (Run r : Run.viewListAllActive()) %7B%0A%09%09%09r.remove();%0A%09%09%7D
+removeRuns();
 %0A%0A%09%7D

Refactor remove runs