/*******************************************************************************
 * Copyright (c) 2015 Red Hat, Inc.
 * Distributed under license by Red Hat, Inc. All rights reserved.
 * This program is made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package com.openshift.internal.restclient.model.v1;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.jboss.dmr.ModelNode;
import org.junit.Before;
import org.junit.Test;

import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry;
import com.openshift.internal.restclient.model.volume.PersistentVolume;
import com.openshift.internal.restclient.model.volume.property.HostPathVolumeProperties;
import com.openshift.internal.restclient.model.volume.property.NfsVolumeProperties;
import com.openshift.restclient.IClient;
import com.openshift.restclient.ResourceKind;
import com.openshift.restclient.model.volume.IPersistentVolume;
import com.openshift.restclient.model.volume.property.IHostPathVolumeProperties;
import com.openshift.restclient.model.volume.property.INfsVolumeProperties;
import com.openshift.restclient.utils.MemoryUnit;
import com.openshift.restclient.utils.Samples;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;


public class PersistentVolumeTest {

	private static final String VERSION = "v1";
	private static final Samples sample = Samples.V1_PERSISTENT_VOLUME;
	private IPersistentVolume pv;
	private IClient client;

	@Before
	public void setUp() {
		client = mock(IClient.class);
		ModelNode node = ModelNode.fromJSONString(sample.getContentAsString());
		pv = new PersistentVolume(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.PERSISTENT_VOLUME));
	}

	@Test
	public void testGetCapacityString() {
		pv.setCapacity(13L, MemoryUnit.Pi);
		long capacity = pv.getCapacity("Ki");
		assertEquals(14293651161088L, capacity);

		capacity = pv.getCapacity("Ti");
		assertEquals(13312L, capacity);

		capacity = pv.getCapacity("Pi");
		assertEquals(13L, capacity);
	}

	@Test
	public void testGetCapacity() {
		pv.setCapacity(13L, MemoryUnit.Pi);
		long capacity = pv.getCapacity();
		assertEquals(14636698788954112L, capacity);
	}

	@Test
	public void testSetCapacity() {
		pv.setCapacity(1L, MemoryUnit.Ki);
		long capacity = pv.getCapacity();
		assertEquals(1024L, capacity);

		pv.setCapacity(31L, MemoryUnit.Ti);
		capacity = pv.getCapacity(MemoryUnit.Ti);
		assertEquals(31L, capacity);
	}

	@Test(expected = ArithmeticException.class)
	public void testSetCapacityOverflow() {
		/*
		 * 2^4 * 2 ^60 = 2^64, LONG_MAX is only 2^64-1
		 */
		pv.setCapacity(16L, MemoryUnit.Ei);
		pv.getCapacity();
	}

	@Test
	public void testGetCapacityUnit() {
		pv.setCapacity(1L, MemoryUnit.Ki);
		MemoryUnit unit = pv.getCapacityUnit();
		assertEquals(MemoryUnit.Ki, unit);

		pv.setCapacity(1L, MemoryUnit.Pi);
		unit = pv.getCapacityUnit();
		assertEquals(MemoryUnit.Pi, unit);
	}

	@Test
	public void testAccessModes() {
		pv.setAccessModes("ReadWriteOnce");
		Set<String> modes = pv.getAccessModes();
		assertTrue(modes.contains("ReadWriteOnce"));

		pv.setAccessModes("ReadWriteOnce", "ReadOnlyMany", "ReadWriteMany");
		modes = pv.getAccessModes();
		Set<String> expected = new HashSet<>();
		expected.addAll(Arrays.asList("ReadWriteOnce", "ReadOnlyMany", "ReadWriteMany"));
		assertTrue(modes.containsAll(expected));
	}

	@Test
	public void testReclaimPolicy() {
		pv.setReclaimPolicy("Recycle");
		String policy = pv.getReclaimPolicy();
		assertEquals(policy, "Recycle");
	}

	@Test
	public void testGetPersistentVolumeProperties() {
		pv.getPersistentVolumeProperties();

	}

	@Test
	public void testNFSVolume() {
		INfsVolumeProperties volume = new NfsVolumeProperties("10.10.10.10", "/tmp/dir", true);
		pv.setPersistentVolumeProperties(volume);
		volume = (INfsVolumeProperties) pv.getPersistentVolumeProperties();
		assertEquals("/tmp/dir", volume.getPath());
		assertEquals("10.10.10.10", volume.getServer());
		assertEquals(true, volume.isReadOnly());
	}

	@Test
	public void testHostPathVolume() {
		IHostPathVolumeProperties volume = new HostPathVolumeProperties("/tmp/dir");
		pv.setPersistentVolumeProperties(volume);
		volume = (IHostPathVolumeProperties) pv.getPersistentVolumeProperties();
		assertEquals("/tmp/dir", volume.getPath());
	}
}
