package com.gentics.mesh.assertj.impl;

import static com.gentics.mesh.core.rest.schema.change.impl.SchemaChangeOperation.UPDATEMICROSCHEMA;
import static com.gentics.mesh.core.rest.schema.change.impl.SchemaChangeOperation.UPDATESCHEMA;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.List;

import org.assertj.core.api.AbstractAssert;

import com.gentics.mesh.core.rest.schema.Schema;
import com.gentics.mesh.core.rest.schema.change.impl.SchemaChangeModel;
import com.gentics.mesh.core.rest.schema.change.impl.SchemaChangeOperation;

import io.vertx.core.json.JsonObject;

public class SchemaChangeModelAssert extends AbstractAssert<SchemaChangeModelAssert, SchemaChangeModel> {

	public SchemaChangeModelAssert(SchemaChangeModel actual) {
		super(actual, SchemaChangeModelAssert.class);
	}

	/**
	 * Assert that the change maps a specific schema operation.
	 * 
	 * @param operation
	 * @return
	 */
	public SchemaChangeModelAssert is(SchemaChangeOperation operation) {
		assertEquals("The operation of the change did not match the expected one.", operation, actual.getOperation());
		return this;
	}

	/**
	 * Assert that the change contains a schema field reference.
	 * 
	 * @param fieldName
	 * @return Fluent API
	 */
	public SchemaChangeModelAssert forField(String fieldName) {
		assertNotNull("The field for this change could not be identified.", actual.getProperty(SchemaChangeModel.FIELD_NAME_KEY));
		assertEquals("The change field name does not match the expected one.", fieldName, actual.getProperty(SchemaChangeModel.FIELD_NAME_KEY));
		return this;
	}

	/**
	 * Assert that the change contains the property with the given key and value.
	 * 
	 * @param key
	 * @param value
	 * @return Fluent API
	 */
	public SchemaChangeModelAssert hasProperty(String key, Object value) {
		assertTrue("The property with key {" + key + "} could not be found within the change.", actual.getProperties().containsKey(key));
		if (value instanceof String[]) {
			Object actualValue = actual.getProperties().get(key);
			if (actualValue instanceof List) {
				actualValue = ((List<Object>) actualValue).toArray();
			}
			// Construct debug information
			String values = "{";
			for (Object obj : (Object[]) actualValue) {
				values += "," + obj.toString();
			}
			values += "}";
			assertArrayEquals("The value for the given property did not match the expected one." + values, (Object[]) value, (Object[]) actualValue);
		} else if (value instanceof JsonObject) {
			Object current = actual.getProperties().get(key);
			assertEquals("The value for the given property did not match the expected one.", ((JsonObject)value).encode(), ((JsonObject)current).encode());
		} else {
			Object current = actual.getProperties().get(key);
			assertEquals("The value for the given property did not match the expected one.", value, current);
		}
		return this;
	}

	/**
	 * Assert that the change does not contain a property with the given key.
	 * 
	 * @param key
	 * @return
	 */
	public SchemaChangeModelAssert hasNoProperty(String key) {
		assertFalse("The property with key {" + key + "} could be found within the change.", actual.getProperties().containsKey(key));
		return this;
	}

	/**
	 * Assert that the change is an field container update operation (either UPDATESCHEMA or UPDATEMICROSCHEMA).
	 * 
	 * @param container
	 * @return
	 */
	public SchemaChangeModelAssert isUpdateOperation(Object container) {
		if (container instanceof Schema) {
			assertEquals("The change operation does not match.", UPDATESCHEMA, actual.getOperation());
		} else {
			assertEquals("The change operation does not match.", UPDATEMICROSCHEMA, actual.getOperation());
		}
		return this;
	}

}

@@ -478,18 +478,72 @@
 .util.Li
-st
+nkedHashMap;%0Aimport java.util.List;%0Aimport java.util.Map
 ;%0A%0Aimpor
@@ -2754,32 +2754,125 @@
 ies().get(key);%0A
+%09%09%09if (current instanceof LinkedHashMap) %7B%0A%09%09%09%09current = new JsonObject((Map) current);%0A%09%09%09%7D%0A
 %09%09%09assertEquals(
@@ -2952,16 +2952,17 @@
 nObject)
+ 
 value).e
@@ -2969,17 +2969,21 @@
 ncode(),
- 
+%0A%09%09%09%09
 ((JsonOb
@@ -2987,16 +2987,17 @@
 nObject)
+ 
 current)

Fix assertion