package io.asfjava.ui.core.schema;

import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;

import java.io.Serializable;

import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

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

import io.asfjava.ui.core.GeneratorFactoryInitializer;
import io.asfjava.ui.core.form.TextField;
import io.asfjava.ui.dto.UiForm;

public class TextFieldFormTest {
	
	static GeneratorFactoryInitializer generatorFactoryInitializer;

	@BeforeClass
	public static void setUpBeforeClass() {
		generatorFactoryInitializer = new GeneratorFactoryInitializer();
		generatorFactoryInitializer.contextInitialized(null);
	}

	@AfterClass
	public static void tearDownAfterClass() {
		generatorFactoryInitializer.contextDestroyed(null);
	}
	
	@Test
	public void testGenerate_textField() throws JsonProcessingException {
		UiForm ui = UiFormSchemaGenerator.get().generate(TextFieldForm.class);
		String json = new ObjectMapper().writeValueAsString(ui);

		Assert.assertThat(json, hasJsonPath("$.schema.properties.firstName.title", equalTo("First Name")));
		Assert.assertThat(json, hasJsonPath("$.schema.properties.firstName.pattern", equalTo("[a-z]")));
		Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')]", hasSize(1)));
		Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')].description",
				hasItem("This is a description for your first name field")));
		Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')].placeholder", hasItem("Your first name")));
		Assert.assertThat(json,
				hasJsonPath("$.form[?(@.key=='firstName')].validationMessage", hasItem("this is a validation msg")));
		// Assert.assertThat(json,
		// hasJsonPath("$.form[?(@.key=='firstName')].type",hasItem("textField")));

	}

	@Test
	public void testGenerate_textField_WithFieldAddonRight() throws JsonProcessingException {
		UiForm ui = UiFormSchemaGenerator.get().generate(TextFieldFormRight.class);
		String json = new ObjectMapper().writeValueAsString(ui);

		Assert.assertThat(json, hasJsonPath("$.schema.properties.firstName.title", equalTo("First Name")));
		Assert.assertThat(json, hasJsonPath("$.schema.properties.firstName.pattern", equalTo("[a-z]")));
		Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')]", hasSize(1)));
		Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')].description",
				hasItem("This is a description for your first name field")));
		Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')].placeholder", hasItem("Your first name")));
		Assert.assertThat(json,
				hasJsonPath("$.form[?(@.key=='firstName')].validationMessage", hasItem("this is a validation msg")));
		Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')].fieldAddonRight", hasItem("@")));

	}

	@Test
	public void testGenerate_textField_WithFieldAddonLeft() throws JsonProcessingException {
		UiForm ui = UiFormSchemaGenerator.get().generate(TextFieldFormLeft.class);
		String json = new ObjectMapper().writeValueAsString(ui);

		Assert.assertThat(json, hasJsonPath("$.schema.properties.firstName.title", equalTo("First Name")));
		Assert.assertThat(json, hasJsonPath("$.schema.properties.firstName.pattern", equalTo("[a-z]")));
		Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')]", hasSize(1)));
		Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')].description",
				hasItem("This is a description for your first name field")));
		Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')].placeholder", hasItem("Your first name")));
		Assert.assertThat(json,
				hasJsonPath("$.form[?(@.key=='firstName')].validationMessage", hasItem("this is a validation msg")));
		Assert.assertThat(json, hasJsonPath("$.form[?(@.key=='firstName')].fieldAddonLeft", hasItem("@")));

	}

}

class TextFieldForm implements Serializable {

	@TextField(title = "First Name", placeHolder = "Your first name", pattern = "[a-z]", noTitle = true, validationMessage = "this is a validation msg", description = "This is a description for your first name field", readOnly = true)
	private String firstName;

	public String getFirstName() {
		return firstName;
	}

}

class TextFieldFormRight implements Serializable {

	@TextField(title = "First Name", placeHolder = "Your first name", fieldAddonRight = "@", pattern = "[a-z]", noTitle = true, validationMessage = "this is a validation msg", description = "This is a description for your first name field")
	private String firstName;

	public String getFirstName() {
		return firstName;
	}

}

class TextFieldFormLeft implements Serializable {

	@TextField(title = "First Name", placeHolder = "Your first name", fieldAddonLeft = "@", pattern = "[a-z]", noTitle = true, validationMessage = "this is a validation msg", description = "This is a description for your first name field")
	private String firstName;

	public String getFirstName() {
		return firstName;
	}

}

@@ -1421,32 +1421,223 @@
 lTo(%22%5Ba-z%5D%22)));%0A
+%09%09Assert.assertThat(json, hasJsonPath(%22$.schema.properties.firstName.minLength%22, equalTo(6)));%0A%09%09Assert.assertThat(json, hasJsonPath(%22$.schema.properties.firstName.maxLength%22, equalTo(10)));%0A
 %09%09Assert.assertT
@@ -2640,32 +2640,223 @@
 lTo(%22%5Ba-z%5D%22)));%0A
+%09%09Assert.assertThat(json, hasJsonPath(%22$.schema.properties.firstName.minLength%22, equalTo(6)));%0A%09%09Assert.assertThat(json, hasJsonPath(%22$.schema.properties.firstName.maxLength%22, equalTo(10)));%0A
 %09%09Assert.assertT
@@ -4574,32 +4574,57 @@
 ttern = %22%5Ba-z%5D%22,
+minLenght=6,maxLenght=10,
  noTitle = true,
@@ -4993,32 +4993,57 @@
 ttern = %22%5Ba-z%5D%22,
+minLenght=6,maxLenght=10,
  noTitle = true,
@@ -5597,28 +5597,30 @@
 %7B%0A%09%09return firstName;%0A%09%7D%0A%0A%7D%0A
+%0A%0A

Refactor Unit test