package com.stripe.net;

import com.stripe.exception.StripeException;
import com.stripe.model.Account;
import com.stripe.net.LiveStripeResponseGetter;
import com.stripe.net.RequestOptions;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;

public class LiveStripeResponseGetterTest {
	LiveStripeResponseGetter srg;

	@Before
	public void before() {
		srg = new LiveStripeResponseGetter();
	}

	/* Kind of hacky, but makes tests readable */
	public String encode(String s) throws UnsupportedEncodingException {
		return s.replace("[", "%5B").replace("]", "%5D");
	}

	@Test
	public void testCreateQuery() throws StripeException, UnsupportedEncodingException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("a", "b");
		assertEquals("a=b", srg.createQuery(params));
	}

	@Test
	public void testCreateQueryWithNestedParams() throws StripeException, UnsupportedEncodingException {
		/* Use LinkedHashMap because it preserves iteration order */
		Map<String, Object> params = new LinkedHashMap<String, Object>();
		Map<String, Object> nested = new LinkedHashMap<String, Object>();
		nested.put("A", "B");
		nested.put("C", "D");
		params.put("nested", nested);
		params.put("c", "d");
		params.put("e", "f");
		assertEquals(encode("nested[A]=B&nested[C]=D&c=d&e=f"), srg.createQuery(params));
	}

	@Test
	public void testCreateQueryWithListParams() throws StripeException, UnsupportedEncodingException {

		List<String> nested = new LinkedList<String>();
		nested.add("A");
		nested.add("B");
		nested.add("C");

		/* Use LinkedHashMap because it preserves iteration order */
		Map<String, Object> params = new LinkedHashMap<String, Object>();
		params.put("nested", nested);
		params.put("a", "b");
		params.put("c", "d");

		assertEquals(encode("nested[]=A&nested[]=B&nested[]=C&a=b&c=d"), srg.createQuery(params));
	}

	// It's really arrays of hashes where things in
	// application/x-www-urlencoded-form start to get *really* hairy, so let's
	// have a special test to cover thsi type of case.
	@Test
	public void testCreateQueryWithComplexParams() throws StripeException, UnsupportedEncodingException {
		List<String> deepNestedList = new LinkedList<String>();
		deepNestedList.add("A");
		deepNestedList.add("B");

		Map<String, String> deepNestedMap1 = new LinkedHashMap<String, String>();
		deepNestedMap1.put("C", "C-1");
		deepNestedMap1.put("D", "D-1");

		Map<String, String> deepNestedMap2 = new LinkedHashMap<String, String>();
		deepNestedMap2.put("C", "C-2");
		deepNestedMap2.put("D", "D-2");

		List<Object> nested = new LinkedList<Object>();
		nested.add(deepNestedList);
		nested.add(deepNestedMap1);
		nested.add(deepNestedMap2);

		/* Use LinkedHashMap because it preserves iteration order */
		Map<String, Object> params = new LinkedHashMap<String, Object>();
		params.put("nested", nested);

		assertEquals(encode("nested[][]=A&nested[][]=B&nested[][C]=C-1&nested[][D]=D-1&nested[][C]=C-2&nested[][D]=D-2"), srg.createQuery(params));
	}

	@Test
	public void testIncorrectAdditionalOwners() throws StripeException, UnsupportedEncodingException {
		Map<String, String> ownerParams = new HashMap<String, String>();
		ownerParams.put("first_name", "Stripe");

		List<Object> additionalOwners = new LinkedList<Object>();
		additionalOwners.add(ownerParams);

		Map<String, Object> legalEntityParams = new HashMap<String, Object>();
		legalEntityParams.put("additional_owners", additionalOwners);

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("legal_entity", legalEntityParams);

		assertEquals(encode("legal_entity[additional_owners][][first_name]=Stripe"), srg.createQuery(params));
	}

	@Test
	public void testCorrectAdditionalOwners() throws StripeException, UnsupportedEncodingException {
		Map<String, String> ownerParams = new HashMap<String, String>();
		ownerParams.put("first_name", "Stripe");

		Map<String, Object> additionalOwnersMap = new HashMap<String, Object>();
		additionalOwnersMap.put("0", ownerParams);

		Map<String, Object> legalEntityParams = new HashMap<String, Object>();
		legalEntityParams.put("additional_owners", additionalOwnersMap);

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("legal_entity", legalEntityParams);

		assertEquals(encode("legal_entity[additional_owners][0][first_name]=Stripe"), srg.createQuery(params));
	}
}

@@ -2130,185 +2130,8 @@
 %09%7D%0A%0A
-%09// It's really arrays of hashes where things in%0A%09// application/x-www-urlencoded-form start to get *really* hairy, so let's%0A%09// have a special test to cover thsi type of case.%0A
 %09@Te
@@ -2169,20 +2169,20 @@
 With
-ComplexParam
+ArrayOfHashe
 s() 
@@ -2240,121 +2240,8 @@
 n %7B%0A
-%09%09List%3CString%3E deepNestedList = new LinkedList%3CString%3E();%0A%09%09deepNestedList.add(%22A%22);%0A%09%09deepNestedList.add(%22B%22);%0A%0A
 %09%09Ma
@@ -2334,22 +2334,22 @@
 p1.put(%22
-C
+A
 %22, %22
-C
+A
 -1%22);%0A%09%09
@@ -2368,22 +2368,22 @@
 p1.put(%22
-D
+B
 %22, %22
-D
+B
 -1%22);%0A%0A%09
@@ -2483,14 +2483,14 @@
 ut(%22
-C
+A
 %22, %22
-C
+A
 -2%22)
@@ -2517,14 +2517,14 @@
 ut(%22
-D
+B
 %22, %22
-D
+B
 -2%22)
@@ -2580,38 +2580,8 @@
 ();%0A
-%09%09nested.add(deepNestedList);%0A
 %09%09ne
@@ -2837,38 +2837,12 @@
 d%5B%5D%5B
+A
 %5D=A
-&nested%5B%5D%5B%5D=B&nested%5B%5D%5BC%5D=C
 -1&n
@@ -2849,20 +2849,20 @@
 ested%5B%5D%5B
-D%5D=D
+B%5D=B
 -1&neste
@@ -2869,12 +2869,12 @@
 d%5B%5D%5B
-C%5D=C
+A%5D=A
 -2&n
@@ -2885,12 +2885,12 @@
 d%5B%5D%5B
-D%5D=D
+B%5D=B
 -2%22)

Remove array of arrays case from test