package com.google.sps.servlets;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.After;

import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import static com.google.sps.tool.Tool.compareJson;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.*;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.IOException;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.google.appengine.tools.development.testing.LocalUserServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import static com.google.appengine.api.datastore.FetchOptions.Builder.withLimit;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Entity;

import com.google.gson.Gson;
import com.google.common.collect.ImmutableMap;
import com.google.sps.data.Card;
import com.google.sps.tool.EntityTestingTool;
import java.util.List; 
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

public final class EditCardServletTest {

  private final LocalServiceTestHelper helper = 
    new LocalServiceTestHelper(
      new LocalDatastoreServiceTestConfig()
        .setDefaultHighRepJobPolicyUnappliedJobPercentage(0),
      new LocalUserServiceTestConfig())
      .setEnvIsAdmin(true).setEnvIsLoggedIn(true)
      .setEnvEmail("test@gmail.com").setEnvAuthDomain("gmail.com");

  private static final Card CURRENT_CARD = new Card("null", "spanish", "en", "es", "hello", "hola");
  private static final Card EDITED_CARD = new Card("null", "vietnamese", "en", "vi", "hello", "xin chào");
  private HttpServletRequest mockRequest;
  private HttpServletResponse mockResponse;
  private StringWriter responseWriter;
  private EditCardServlet servlet;
  private DatastoreService datastore;
    
  @Before
  public void setUp() throws Exception {
    helper.setUp();
    servlet = new EditCardServlet();
    mockRequest = mock(HttpServletRequest.class);
    mockResponse = mock(HttpServletResponse.class);
    
    // Set up a fake HTTP response 
    responseWriter = new StringWriter();
    when(mockResponse.getWriter()).thenReturn(new PrintWriter(responseWriter));

    // Initialize datastore
    datastore = DatastoreServiceFactory.getDatastoreService();
  }

  @After
  public void tearDown() throws Exception {
    helper.tearDown();
  }

  @Test
  public void EditCard() throws Exception {
    
    // Generate a dummy Folder Entity
    Entity FOLDER_A = new Entity("Folder", "testID");
    String FOLDERKEY = KeyFactory.keyToString(FOLDER_A.getKey());

    Card cardInDatastore = EntityTestingTool.populateDatastoreWithACard(CURRENT_CARD, datastore, FOLDERKEY);
    String cardKey = cardInDatastore.getCardKey();

    // Make sure the expected Card has the same key
    EDITED_CARD.setCardKey(cardKey);

    when(mockRequest.getParameter("labels")).thenReturn("vietnamese");
    when(mockRequest.getParameter("fromLang")).thenReturn("en");
    when(mockRequest.getParameter("toLang")).thenReturn("vi");
    when(mockRequest.getParameter("cardKey")).thenReturn(cardKey);
    when(mockRequest.getParameter("rawText")).thenReturn("hello");
    when(mockRequest.getParameter("testStatus")).thenReturn("True");

    servlet.doPut(mockRequest, mockResponse);

    Entity editedCard = datastore.get(KeyFactory.stringToKey(cardKey));

    String response = new Gson().toJson(new Card(editedCard));
    String expectedResponse = new Gson().toJson(EDITED_CARD);

    assertEquals(response, expectedResponse);
  }
}
@@ -2102,216 +2102,8 @@
 );%0A%0A
-  private static final Card CURRENT_CARD = new Card(%22null%22, %22spanish%22, %22en%22, %22es%22, %22hello%22, %22hola%22);%0A  private static final Card EDITED_CARD = new Card(%22null%22, %22vietnamese%22, %22en%22, %22vi%22, %22hello%22, %22xin ch%C3%A0o%22);%0A
   pr
@@ -2898,24 +2898,195 @@
  Exception %7B
+%0A%0A    Card currentCard = new Card(%22null%22, %22spanish%22, %22en%22, %22es%22, %22hello%22, %22hola%22);%0A    Card expectedCard = new Card(%22null%22, %22vietnamese%22, %22en%22, %22vi%22, %22hello%22, %22xin ch%C3%A0o%22);
 %0A    %0A    //
@@ -3128,24 +3128,22 @@
  Entity 
-FOLDER_A
+folder
  = new E
@@ -3180,25 +3180,25 @@
  String 
-FOLDERKEY
+folderKey
  = KeyFa
@@ -3219,16 +3219,14 @@
 ing(
-FOLDER_A
+folder
 .get
@@ -3310,20 +3310,19 @@
 ard(
-CURRENT_CARD
+currentCard
 , da
@@ -3334,17 +3334,17 @@
 re, 
-FOLDERKEY
+folderKey
 );%0A 
@@ -4118,27 +4118,28 @@
 .toJson(
-EDITED_CARD
+expectedCard
 );%0A%0A    

Fix name styling issue in EditCardServletTest.java