package jp.sourceforge.orangesignal.ta.dataset;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

import java.util.Calendar;

import jp.sourceforge.orangesignal.ta.dataset.TimeSeriesDataset.Interval;
import jp.sourceforge.orangesignal.ta.dataset.loader.PriceDataLoader;

import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

public class TimeSeriesDatasetTest {

	private static PriceData[] prces;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		prces = new PriceDataLoader().load("src/test/resources/data/n225.csv").toArray(new PriceData[]{});
	}

	@Test
	public void testGetSymbol() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.DAILY);
		assertNull(dataset.getSymbol());
	}

	@Test
	public void testSetSymbol() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.DAILY);
		dataset.setSymbol("n225");
		assertThat(dataset.getSymbol(), is("n225"));
	}

	@Test
	public void testGetSymbolName() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.DAILY);
		assertNull(dataset.getSymbolName());
	}

	@Test
	public void testSetSymbolName() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.DAILY);
		dataset.setSymbolName("日経平均株価 225種");
		assertThat(dataset.getSymbolName(), is("日経平均株価 225種"));
	}

	@Test
	public void testTimeSeriesDatasetInterval() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.HOURLY);
		assertThat(dataset.getInterval(), is(Interval.HOURLY));
	}

	@Test(expected = NullPointerException.class)
	public void testTimeSeriesDatasetIntervalNullPointerException() {
		final Interval interval = null;
		new TimeSeriesDataset(interval);
	}

	@Test
	public void testTimeSeriesDatasetIntervalPriceDataArray() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.DAILY, prces);
		assertThat(dataset.getInterval(), is(Interval.DAILY));
		assertNotNull(dataset.getDate());
		assertThat(dataset.getLength(), is(not(0)));
	}

	@Test(expected = NullPointerException.class)
	public void testTimeSeriesDatasetIntervalPriceDataArrayNullPointerException() {
		final Interval interval = null;
		new TimeSeriesDataset(interval, prces);
		new TimeSeriesDataset(Interval.DAILY, null);
	}

	@Test
	public void testTimeSeriesDatasetIntervalPriceDataArrayMarginDataArraySplitDataArray() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.DAILY, prces, null, null);
		assertThat(dataset.getInterval(), is(Interval.DAILY));
		assertNotNull(dataset.getDate());
		assertThat(dataset.getLength(), is(not(0)));
	}

	@Test
	public void testTimeSeriesDatasetTimeSeriesDataset() {
		final TimeSeriesDataset dataset1 = new TimeSeriesDataset(Interval.DAILY, prces);
		dataset1.setSymbol("n225");
		dataset1.setSymbolName("日経平均株価 225種");
		final TimeSeriesDataset dataset2 = new TimeSeriesDataset(dataset1);
		assertThat(dataset2.getInterval(), is(Interval.DAILY));
		assertNotNull(dataset2.getDate());
		assertThat(dataset2.getLength(), is(not(0)));
		assertThat(dataset2.getSymbol(), is("n225"));
		assertThat(dataset2.getSymbolName(), is("日経平均株価 225種"));
	}

	@Test
	public void testGetInterval() {
		assertThat(new TimeSeriesDataset(Interval.DAILY).getInterval(), is(Interval.DAILY));
		assertThat(new TimeSeriesDataset(Interval.HOURLY).getInterval(), is(Interval.HOURLY));
		assertThat(new TimeSeriesDataset(Interval.MINUTELY).getInterval(), is(Interval.MINUTELY));
		assertThat(new TimeSeriesDataset(Interval.MONTHLY).getInterval(), is(Interval.MONTHLY));
		assertThat(new TimeSeriesDataset(Interval.WEEKLY).getInterval(), is(Interval.WEEKLY));
	}

	@Test
	public void testGetLength() {
		assertThat(new TimeSeriesDataset(Interval.DAILY).getLength(), is(0));
	}

	@Test
	public void testGetDate() {
		assertNull(new TimeSeriesDataset(Interval.DAILY).getDate());
	}

	@Test
	public void testGetDateInt() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.DAILY, prces);
		assertNotNull(dataset.getDate(0));
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testIndexOf() {
		fail("まだ実装されていません");
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testLastIndexOf() {
		fail("まだ実装されていません");
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testDefaultIndexOf() {
		fail("まだ実装されていません");
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testDefaultLastIndexOf() {
		fail("まだ実装されていません");
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testGetPeriod() {
		fail("まだ実装されていません");
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testGetPrice() {
		fail("まだ実装されていません");
	}

	@Test
	public void testGetOpen() {
		assertNull(new TimeSeriesDataset(Interval.DAILY).getOpen());
	}

	@Test
	public void testGetOpenInt() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.DAILY, prces);
		assertNotNull(dataset.getOpen(0));
	}

	@Test
	public void testGetHigh() {
		assertNull(new TimeSeriesDataset(Interval.DAILY).getHigh());
	}

	@Test
	public void testGetHighInt() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.DAILY, prces);
		assertNotNull(dataset.getHigh(0));
	}

	@Test
	public void testGetLow() {
		assertNull(new TimeSeriesDataset(Interval.DAILY).getLow());
	}

	@Test
	public void testGetLowInt() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.DAILY, prces);
		assertNotNull(dataset.getLow(0));
	}

	@Test
	public void testGetClose() {
		assertNull(new TimeSeriesDataset(Interval.DAILY).getClose());
	}

	@Test
	public void testGetCloseInt() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.DAILY, prces);
		assertNotNull(dataset.getClose(0));
	}

	@Test
	public void testGetVolume() {
		assertNull(new TimeSeriesDataset(Interval.DAILY).getVolume());
	}

	@Test
	public void testGetVolumeInt() {
		final TimeSeriesDataset dataset = new TimeSeriesDataset(Interval.DAILY, prces);
		assertNotNull(dataset.getVolume(0));
	}

	@Test
	public void testGetSold() {
		assertNull(new TimeSeriesDataset(Interval.DAILY).getSold());
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testGetSoldInt() {
		fail("まだ実装されていません");
	}

	@Test
	public void testGetBought() {
		assertNull(new TimeSeriesDataset(Interval.DAILY).getBought());
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testGetBoughtInt() {
		fail("まだ実装されていません");
	}

	@Test
	public void testGetSplit() {
		assertNull(new TimeSeriesDataset(Interval.DAILY).getSplit());
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testGetSplitInt() {
		fail("まだ実装されていません");
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testGetData() {
		fail("まだ実装されていません");
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testSetData() {
		fail("まだ実装されていません");
	}

	@Test
	public void testIsSplited() {
		assertFalse(new TimeSeriesDataset(Interval.DAILY).isSplited());
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testSplit() {
		fail("まだ実装されていません");
	}

	@Ignore("現バージョンではテスト対象外とする")
	@Test
	public void testExtend() {
		fail("まだ実装されていません");
	}

	@Test
	public void testCompressInterval() {
		final TimeSeriesDataset dataset1 = new TimeSeriesDataset(Interval.DAILY, prces);
		final TimeSeriesDataset dataset2 = dataset1.compress(Interval.MONTHLY);
		assertThat(dataset2.getInterval(), is(Interval.MONTHLY));
		assertNotNull(dataset2.getDate());
		assertThat(dataset2.getLength(), is(not(0)));
	}

	@Test(expected = IllegalArgumentException.class)
	public void testCompressIntervalIllegalArgumentException() {
		final TimeSeriesDataset dataset1 = new TimeSeriesDataset(Interval.DAILY, prces);
		dataset1.compress(Interval.HOURLY);
	}

	@Test
	public void testCompressIntervalCalendar() {
		final TimeSeriesDataset dataset1 = new TimeSeriesDataset(Interval.DAILY, prces);
		final TimeSeriesDataset dataset2 = dataset1.compress(Interval.WEEKLY, Calendar.getInstance());
		assertThat(dataset2.getInterval(), is(Interval.WEEKLY));
		assertNotNull(dataset2.getDate());
		assertThat(dataset2.getLength(), is(not(0)));
	}

	@Test(expected = IllegalArgumentException.class)
	public void testCompressIntervalCalendarIllegalArgumentException() {
		final TimeSeriesDataset dataset1 = new TimeSeriesDataset(Interval.DAILY, prces);
		dataset1.compress(Interval.HOURLY, Calendar.getInstance());
	}

	@Test
	public void testCompressIntervalCalendarDateTruncater() {
		final TimeSeriesDataset dataset1 = new TimeSeriesDataset(Interval.DAILY, prces);
		final TimeSeriesDataset dataset2 = dataset1.compress(Interval.MONTHLY, Calendar.getInstance(), new DateTruncater());
		assertThat(dataset2.getInterval(), is(Interval.MONTHLY));
		assertNotNull(dataset2.getDate());
		assertThat(dataset2.getLength(), is(not(0)));
	}

	@Test(expected = IllegalArgumentException.class)
	public void testCompressIntervalCalendarDateTruncaterIllegalArgumentException() {
		final TimeSeriesDataset dataset1 = new TimeSeriesDataset(Interval.DAILY, prces);
		dataset1.compress(Interval.HOURLY, Calendar.getInstance(), new DateTruncater());
	}

}
