package org.eclipse.mdm.query.entity;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.time.LocalDateTime;
import java.util.Optional;

import org.eclipse.mdm.api.base.adapter.Attribute;
import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.file.FileService.FileServiceType;
import org.eclipse.mdm.api.base.model.Enumeration;
import org.eclipse.mdm.api.base.model.EnumerationValue;
import org.eclipse.mdm.api.base.model.FileLink;
import org.eclipse.mdm.api.base.model.MDMFile;
import org.eclipse.mdm.api.base.model.MimeType;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.model.ValueType;
import org.eclipse.mdm.api.base.query.Record;
import org.eclipse.mdm.api.base.query.Result;
import org.eclipse.mdm.api.odsadapter.utils.ODSEnum;
import org.eclipse.mdm.businessobjects.utils.serialize.MDMJacksonModule;
import org.eclipse.mdm.query.util.Util;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ColumnTest {

	public static ObjectMapper mapper = new ObjectMapper();

	public static Util queryUtil;

	@BeforeClass
	public static void init() {
		mapper.registerModule(new MDMJacksonModule());
		// TODO
		queryUtil = new Util(null);
	}

	@Test
	public void testString() throws JsonProcessingException {
		EntityType e = Mockito.mock(EntityType.class);
		when(e.getName()).thenReturn("TestStep");

		Record record = new Record(e);
		Result result = new Result();
		result.addRecord(record);

		Attribute attrString = createAttribute(e, "myString");
		Value valString = ValueType.STRING.create(attrString.getName(), "eins");
		record.addValue(valString);

		Column colString = queryUtil.convertColumn(result, Optional.of(attrString));
		assertThat(mapper.writeValueAsString(colString)).isEqualTo(
				"{\"type\":\"TestStep\",\"attribute\":\"myString\",\"valueType\":\"STRING\",\"value\":\"eins\"}");
	}

	@Test
	public void testStringSequence() throws JsonProcessingException {
		EntityType e = Mockito.mock(EntityType.class);
		when(e.getName()).thenReturn("TestStep");

		Record record = new Record(e);
		Result result = new Result();
		result.addRecord(record);

		Attribute attrStringSeq = createAttribute(e, "myStringSeq");
		Value valStringSeq = ValueType.STRING_SEQUENCE.create(attrStringSeq.getName(),
				new String[] { "eins", "zwei", "drei" });
		record.addValue(valStringSeq);

		Column colStringSeq = queryUtil.convertColumn(result, Optional.of(attrStringSeq));
		assertThat(mapper.writeValueAsString(colStringSeq)).isEqualTo(
				"{\"type\":\"TestStep\",\"attribute\":\"myStringSeq\",\"valueType\":\"STRING_SEQUENCE\",\"value\":[\"eins\",\"zwei\",\"drei\"]}");
	}

	@Test
	public void testDate() throws JsonProcessingException {
		EntityType e = Mockito.mock(EntityType.class);
		when(e.getName()).thenReturn("TestStep");

		Record record = new Record(e);
		Result result = new Result();
		result.addRecord(record);

		Attribute attrDate = createAttribute(e, "myDate");
		Value valDate = ValueType.DATE.create(attrDate.getName(), LocalDateTime.of(2022, 5, 10, 12, 13, 14));
		record.addValue(valDate);

		Column colDate = queryUtil.convertColumn(result, Optional.of(attrDate));
		assertThat(mapper.writeValueAsString(colDate)).isEqualTo(
				"{\"type\":\"TestStep\",\"attribute\":\"myDate\",\"valueType\":\"DATE\",\"value\":\"2022-05-10T12:13:14Z\"}");
	}

	@Test
	public void testDateSequence() throws JsonProcessingException {
		EntityType e = Mockito.mock(EntityType.class);
		when(e.getName()).thenReturn("TestStep");

		Record record = new Record(e);
		Result result = new Result();
		result.addRecord(record);

		Attribute attrDateSeq = createAttribute(e, "myDateSeq");
		Value valDateSeq = ValueType.DATE_SEQUENCE.create(attrDateSeq.getName(),
				new LocalDateTime[] { LocalDateTime.of(2021, 5, 10, 12, 13, 14),
						LocalDateTime.of(2022, 5, 12, 12, 13, 14), LocalDateTime.of(2022, 5, 10, 1, 2, 3) });
		record.addValue(valDateSeq);

		Column colDateSeq = queryUtil.convertColumn(result, Optional.of(attrDateSeq));
		assertThat(mapper.writeValueAsString(colDateSeq)).isEqualTo(
				"{\"type\":\"TestStep\",\"attribute\":\"myDateSeq\",\"valueType\":\"DATE_SEQUENCE\",\"value\":[\"2021-05-10T12:13:14Z\",\"2022-05-12T12:13:14Z\",\"2022-05-10T01:02:03Z\"]}");
	}

	@Test
	public void testInteger() throws JsonProcessingException {
		EntityType e = Mockito.mock(EntityType.class);
		when(e.getName()).thenReturn("TestStep");

		Record record = new Record(e);
		Result result = new Result();
		result.addRecord(record);

		Attribute attrInteger = createAttribute(e, "myInteger");
		Value valInteger = ValueType.INTEGER.create(attrInteger.getName(), 42);
		record.addValue(valInteger);

		Column colInteger = queryUtil.convertColumn(result, Optional.of(attrInteger));
		assertThat(mapper.writeValueAsString(colInteger)).isEqualTo(
				"{\"type\":\"TestStep\",\"attribute\":\"myInteger\",\"valueType\":\"INTEGER\",\"value\":42}");
	}

	@Test
	public void testIntegerSequence() throws JsonProcessingException {
		EntityType e = Mockito.mock(EntityType.class);
		when(e.getName()).thenReturn("TestStep");

		Record record = new Record(e);
		Result result = new Result();
		result.addRecord(record);

		Attribute attrIntegerSeq = createAttribute(e, "myIntegerSeq");
		Value valIntegerSeq = ValueType.INTEGER_SEQUENCE.create(attrIntegerSeq.getName(), new int[] { 1, 2, 3 });
		record.addValue(valIntegerSeq);

		Column colIntegerSeq = queryUtil.convertColumn(result, Optional.of(attrIntegerSeq));
		assertThat(mapper.writeValueAsString(colIntegerSeq)).isEqualTo(
				"{\"type\":\"TestStep\",\"attribute\":\"myIntegerSeq\",\"valueType\":\"INTEGER_SEQUENCE\",\"value\":[1,2,3]}");
	}

	@Test
	public void testFileLink() throws JsonProcessingException {
		EntityType e = Mockito.mock(EntityType.class);
		when(e.getName()).thenReturn("TestStep");

		Record record = new Record(e);
		Result result = new Result();
		result.addRecord(record);

		Attribute attrFileLink = createAttribute(e, "myFileLink");
		Value valFileLink = ValueType.FILE_LINK.create(attrFileLink.getName(), FileLink.newRemote("/path/test.txt",
				new MimeType("text/plain"), "Test file", 42, null, FileServiceType.EXTREF));
		record.addValue(valFileLink);

		Column colFileLink = queryUtil.convertColumn(result, Optional.of(attrFileLink));
		assertThat(mapper.writeValueAsString(colFileLink)).isEqualTo(
				"{\"type\":\"TestStep\",\"attribute\":\"myFileLink\",\"valueType\":\"FILE_LINK\",\"value\":{\"identifier\":\"EXTREF:/path/test.txt\",\"mimeType\":\"text/plain\",\"description\":\"Test file\",\"fileName\":\"test.txt\"}}");
	}

	@Test
	public void testFileLinkSequence() throws JsonProcessingException {
		EntityType e = Mockito.mock(EntityType.class);
		when(e.getName()).thenReturn("TestStep");

		Record record = new Record(e);
		Result result = new Result();
		result.addRecord(record);

		MDMFile mdmFile = mock(MDMFile.class);
		when(mdmFile.getOriginalFileName()).thenReturn("test2.txt");

		Attribute attrFileLinkSeq = createAttribute(e, "myFileLinkSeq");
		Value valFileLinkSeq = ValueType.FILE_LINK_SEQUENCE.create(attrFileLinkSeq.getName(),
				new FileLink[] {
						FileLink.newRemote("/path/test.txt", new MimeType("text/plain"), "Test file (ExtRef)", 42, null,
								FileServiceType.EXTREF),
						FileLink.newRemote("/path/test2.txt", new MimeType("text/plain"), "Test file (AoFile)", 147,
								mdmFile, FileServiceType.AOFILE) });
		record.addValue(valFileLinkSeq);

		Column colFileLinkSeq = queryUtil.convertColumn(result, Optional.of(attrFileLinkSeq));
		assertThat(mapper.writeValueAsString(colFileLinkSeq)).isEqualTo(
				"{\"type\":\"TestStep\",\"attribute\":\"myFileLinkSeq\",\"valueType\":\"FILE_LINK_SEQUENCE\",\"value\":["
						+ "{\"identifier\":\"EXTREF:/path/test.txt\",\"mimeType\":\"text/plain\",\"description\":\"Test file (ExtRef)\",\"fileName\":\"test.txt\"},"
						+ "{\"identifier\":\"AOFILE:null:null\",\"mimeType\":\"text/plain\",\"description\":\"Test file (AoFile)\",\"fileName\":\"test2.txt\"}]}");
	}

	@Test
	public void testEnum() throws JsonProcessingException {
		EntityType e = Mockito.mock(EntityType.class);
		when(e.getName()).thenReturn("TestStep");

		Record record = new Record(e);
		Result result = new Result();
		result.addRecord(record);

		Attribute attrEnum = createAttribute(e, "myEnum");
		Enumeration<EnumerationValue> enumeration = createEnumeration();
		Value valEnum = ValueType.ENUMERATION.create(enumeration, attrEnum.getName());
		valEnum.set(enumeration.valueOf("red_pill"));
		record.addValue(valEnum);

		Column colEnum = queryUtil.convertColumn(result, Optional.of(attrEnum));
		assertThat(mapper.writeValueAsString(colEnum)).isEqualTo(
				"{\"type\":\"TestStep\",\"attribute\":\"myEnum\",\"valueType\":\"ENUMERATION\",\"value\":\"red_pill\"}");
	}

	@Test
	public void testEnumSequence() throws JsonProcessingException {
		EntityType e = Mockito.mock(EntityType.class);
		when(e.getName()).thenReturn("TestStep");

		Record record = new Record(e);
		Result result = new Result();
		result.addRecord(record);

		Attribute attrEnumSeq = createAttribute(e, "myEnumSeq");
		Enumeration<EnumerationValue> enumeration = createEnumeration();
		Value valEnumSeq = ValueType.ENUMERATION_SEQUENCE.create(enumeration, attrEnumSeq.getName());
		valEnumSeq.set(new EnumerationValue[] { enumeration.valueOf("red_pill"), enumeration.valueOf("blue_pill") });
		record.addValue(valEnumSeq);

		Column colEnumSeq = queryUtil.convertColumn(result, Optional.of(attrEnumSeq));
		assertThat(mapper.writeValueAsString(colEnumSeq)).isEqualTo(
				"{\"type\":\"TestStep\",\"attribute\":\"myEnumSeq\",\"valueType\":\"ENUMERATION_SEQUENCE\",\"value\":[\"red_pill\",\"blue_pill\"]}");
	}

	private Enumeration<EnumerationValue> createEnumeration() {
		Enumeration<EnumerationValue> enumeration = new Enumeration<>("MDM", EnumerationValue.class, "choice");
		enumeration.addValue(new ODSEnum("red_pill", 0));
		enumeration.addValue(new ODSEnum("blue_pill", 1));
		return enumeration;
	}

	private Attribute createAttribute(EntityType e, String name) {
		Attribute attribute = Mockito.mock(Attribute.class);
		when(attribute.getEntityType()).thenReturn(e);
		when(attribute.getName()).thenReturn(name);

		return attribute;
	}
}
