using System;
using System.Data;
using System.IO;
using NUnit.Framework;

namespace Orciid.Media.Util
{
	[TestFixture]
	public class TestCsvParser
	{
		[Test]
		public void UnquotedLine()
		{
			DataTable table = CsvParser.Parse("one,two,three");
			Assert.IsNotNull(table);
			Assert.AreEqual(3, table.Columns.Count);
			Assert.AreEqual(1, table.Rows.Count);
			Assert.AreEqual("one", table.Rows[0][0]);
			Assert.AreEqual("two", table.Rows[0][1]);
			Assert.AreEqual("three", table.Rows[0][2]);
		}

		[Test]
		public void UnquotedTabbedLine()
		{
			DataTable table = CsvParser.Parse("one\ttwo\tthree", false, '\t');
			Assert.IsNotNull(table);
			Assert.AreEqual(3, table.Columns.Count);
			Assert.AreEqual(1, table.Rows.Count);
			Assert.AreEqual("one", table.Rows[0][0]);
			Assert.AreEqual("two", table.Rows[0][1]);
			Assert.AreEqual("three", table.Rows[0][2]);
		}

		[Test]
		public void QuotedTabs()
		{
			DataTable table = CsvParser.Parse("\"one\ttab\"\t\"two\t\ttabs\"\t\"three\t\t\ttabs\"", false, '\t');
			Assert.IsNotNull(table);
			Assert.AreEqual(3, table.Columns.Count);
			Assert.AreEqual(1, table.Rows.Count);
			Assert.AreEqual("one\ttab", table.Rows[0][0]);
			Assert.AreEqual("two\t\ttabs", table.Rows[0][1]);
			Assert.AreEqual("three\t\t\ttabs", table.Rows[0][2]);
		}

		[Test]
		public void QuotedLine()
		{
			DataTable table = CsvParser.Parse("\"one\",\"two\",\"three\"");
			Assert.IsNotNull(table);
			Assert.AreEqual(3, table.Columns.Count);
			Assert.AreEqual(1, table.Rows.Count);
			Assert.AreEqual("one", table.Rows[0][0]);
			Assert.AreEqual("two", table.Rows[0][1]);
			Assert.AreEqual("three", table.Rows[0][2]);
		}

		[Test]
		public void TwoLines()
		{
			DataTable table = CsvParser.Parse("one,two,three\nfour,five,six\n");
			Assert.IsNotNull(table);
			Assert.AreEqual(3, table.Columns.Count);
			Assert.AreEqual(2, table.Rows.Count);
			Assert.AreEqual("one", table.Rows[0][0]);
			Assert.AreEqual("two", table.Rows[0][1]);
			Assert.AreEqual("three", table.Rows[0][2]);
			Assert.AreEqual("four", table.Rows[1][0]);
			Assert.AreEqual("five", table.Rows[1][1]);
			Assert.AreEqual("six", table.Rows[1][2]);
		}

		[Test]
		public void QuotedMultilineValue()
		{
			DataTable table = CsvParser.Parse("\"one\n\"\"beer\"\"\",\"\"\"two\"\"\nbeers\",\"three\nbeers\"");
			Assert.IsNotNull(table);
			Assert.AreEqual(3, table.Columns.Count);
			Assert.AreEqual(1, table.Rows.Count);
			Assert.AreEqual("one\n\"beer\"", table.Rows[0][0]);
			Assert.AreEqual("\"two\"\nbeers", table.Rows[0][1]);
			Assert.AreEqual("three\nbeers", table.Rows[0][2]);
		}

		[Test]
		public void Headers()
		{
			DataTable table = CsvParser.Parse("First,Last,Email\nAndreas,Knab,knab2ar@jmu.edu", true);
			Assert.IsNotNull(table);
			Assert.AreEqual(3, table.Columns.Count);
			Assert.AreEqual(1, table.Rows.Count);
			Assert.AreEqual("Andreas", table.Rows[0]["First"]);
			Assert.AreEqual("Knab", table.Rows[0]["Last"]);
			Assert.AreEqual("knab2ar@jmu.edu", table.Rows[0]["Email"]);
		}

		[Test]
		public void TrailingNewlines()
		{
			DataTable table = CsvParser.Parse("test\n\n\n\n\n\n");
			Assert.IsNotNull(table);
			Assert.AreEqual(1, table.Columns.Count);
			Assert.AreEqual(6, table.Rows.Count);
			Assert.AreEqual("test", table.Rows[0][0]);
		}

		[Test]
		public void Newlines()
		{
			DataTable table = CsvParser.Parse("test1\x0Atest2\x0Dtest3\x0D\x0Atest4");
			Assert.IsNotNull(table);
			Assert.AreEqual(1, table.Columns.Count);
			Assert.AreEqual(4, table.Rows.Count);
			Assert.AreEqual("test1", table.Rows[0][0]);
			Assert.AreEqual("test2", table.Rows[1][0]);
			Assert.AreEqual("test3", table.Rows[2][0]);
			Assert.AreEqual("test4", table.Rows[3][0]);
		}

		[Test]
		public void SimpleCsvFile()
		{
			DataTable table = CsvParser.Parse(
				"ID,Title,Author,Subject,Resource\n" +
				"ABC123,How to eat a bunny,Andreas,Cartoons,ABC123.jpg\n" +
				"TAB1,\"This has 	 a tab\",Andreas,Test,TAB1.jpg", true);

			Assert.IsNotNull(table);
			Assert.AreEqual(5, table.Columns.Count);
			Assert.AreEqual(2, table.Rows.Count);
		}
	}
}
