/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package org.apache.geode.rest.internal.web.controllers;

import static org.apache.geode.test.matchers.JsonEquivalence.jsonEquals;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.head;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.IntStream;

import com.jayway.jsonpath.JsonPath;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.GenericXmlWebContextLoader;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.context.web.WebMergedContextConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;

import org.apache.geode.cache.CacheLoader;
import org.apache.geode.cache.CacheWriter;
import org.apache.geode.cache.CacheWriterException;
import org.apache.geode.cache.Declarable;
import org.apache.geode.cache.EntryEvent;
import org.apache.geode.cache.LoaderHelper;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionDestroyedException;
import org.apache.geode.cache.RegionEvent;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.TimeoutException;
import org.apache.geode.cache.execute.FunctionService;
import org.apache.geode.internal.cache.HttpService;
import org.apache.geode.management.internal.RestAgent;
import org.apache.geode.pdx.PdxInstance;
import org.apache.geode.test.junit.rules.ServerStarterRule;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:WEB-INF/geode-servlet.xml"},
    loader = TestContextLoader.class)
@WebAppConfiguration
public class RestAccessControllerTest {

  private static final String BASE_URL = "http://localhost/v1";

  private static final String ORDER1_JSON = "order1.json";
  private static final String ORDER1_ARRAY_JSON = "order1-array.json";
  private static final String ORDER1_NO_TYPE_JSON = "order1-no-type.json";
  private static final String ORDER2_JSON = "order2.json";
  private static final String ORDER2_UPDATED_JSON = "order2-updated.json";
  private static final String MALFORMED_JSON = "malformed.json";
  private static final String CUSTOMER_LIST_JSON = "customer-list.json";
  private static final String CUSTOMER_LIST_NO_TYPE_JSON = "customer-list-no-type.json";
  private static final String ORDER_CAS_JSON = "order-cas.json";
  private static final String ORDER_CAS_OLD_JSON = "order-cas-old.json";
  private static final String ORDER_CAS_NEW_JSON = "order-cas-new.json";
  private static final String ORDER_CAS_WRONG_OLD_JSON = "order-cas-wrong-old.json";

  private static Map<String, String> jsonResources = new HashMap<>();

  private static RequestPostProcessor POST_PROCESSOR = new StandardRequestPostProcessor();

  private MockMvc mockMvc;

  private static Region<?, ?> orderRegion;
  private static Region<?, ?> customerRegion;

  @ClassRule
  public static ServerStarterRule rule = new ServerStarterRule()
      .withProperty("log-level", "warn")
      .withPDXReadSerialized()
      .withRegion(RegionShortcut.REPLICATE, "customers")
      .withRegion(RegionShortcut.REPLICATE, "orders");

  @Autowired
  private WebApplicationContext webApplicationContext;

  @BeforeClass
  public static void setupCClass() throws Exception {
    loadResource(ORDER1_JSON);
    loadResource(ORDER1_ARRAY_JSON);
    loadResource(ORDER1_NO_TYPE_JSON);
    loadResource(ORDER2_JSON);
    loadResource(MALFORMED_JSON);
    loadResource(CUSTOMER_LIST_JSON);
    loadResource(CUSTOMER_LIST_NO_TYPE_JSON);
    loadResource(ORDER2_UPDATED_JSON);
    loadResource(ORDER_CAS_JSON);
    loadResource(ORDER_CAS_OLD_JSON);
    loadResource(ORDER_CAS_NEW_JSON);
    loadResource(ORDER_CAS_WRONG_OLD_JSON);

    RestAgent.createParameterizedQueryRegion();

    FunctionService.registerFunction(new AddFreeItemToOrders());
    FunctionService.registerFunction(new EchoArgumentFunction());

    rule.createRegion(RegionShortcut.REPLICATE_PROXY, "empty",
        f -> f.setCacheLoader(new SimpleCacheLoader()).setCacheWriter(new SimpleCacheWriter()));

    customerRegion = rule.getCache().getRegion("customers");
    orderRegion = rule.getCache().getRegion("orders");
  }

  private static void loadResource(String name) throws Exception {
    URL orderCasJson = RestAccessControllerTest.class.getResource(name);
    jsonResources.put(name, new String(Files.readAllBytes(Paths.get(orderCasJson.toURI()))));
  }

  @Before
  public void setup() {
    mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();

    customerRegion.clear();
    orderRegion.clear();
  }

  @Test
  @WithMockUser
  public void postEntry() throws Exception {
    mockMvc.perform(post("/v1/orders?key=1")
        .content(jsonResources.get(ORDER1_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isCreated())
        .andExpect(header().string("Location", BASE_URL + "/orders/1"));

    mockMvc.perform(post("/v1/orders?key=1")
        .content(jsonResources.get(ORDER1_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isConflict());

    Order order = (Order) ((PdxInstance) orderRegion.get("1")).getObject();
    assertThat(order).as("order should not be null").isNotNull();
  }

  @Test
  @WithMockUser
  public void postEntryWithJsonArrayOfOrders() throws Exception {
    mockMvc.perform(post("/v1/orders?key=1")
        .content(jsonResources.get(ORDER1_ARRAY_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isCreated())
        .andExpect(header().string("Location", BASE_URL + "/orders/1"));

    mockMvc.perform(post("/v1/orders?key=1")
        .content(jsonResources.get(ORDER1_ARRAY_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isConflict());

    List<PdxInstance> entries = (List<PdxInstance>) orderRegion.get("1");
    Order order = (Order) entries.get(0).getObject();
    assertThat(order).as("order should not be null").isNotNull();
  }

  @Test
  @WithMockUser
  public void failPostEntryWithInvalidJson() throws Exception {
    mockMvc.perform(post("/v1/orders?key=1")
        .content(jsonResources.get(MALFORMED_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isBadRequest())
        .andExpect(
            jsonPath("$.cause", is("Json doc specified is either not supported or invalid!")));
  }

  @Test
  @WithMockUser
  public void failPostEntryWithInvalidRegion() throws Exception {
    mockMvc.perform(post("/v1/unknown?key=1")
        .content(jsonResources.get(ORDER1_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound())
        .andExpect(
            jsonPath("$.cause", is("The Region identified by name (unknown) could not be found!")));
  }

  @Test
  @WithMockUser
  public void failPostEntryOnRegionWithDataPolicyEmpty() throws Exception {
    mockMvc.perform(post("/v1/empty?key=1")
        .content(jsonResources.get(ORDER1_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isInternalServerError())
        .andExpect(
            jsonPath("$.message",
                is("Resource (empty) configuration does not support the requested operation!")));
  }

  @Test
  @WithMockUser
  public void failGettingEntryFromUnknownRegion() throws Exception {
    mockMvc.perform(get("/v1/unknown/10")
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound())
        .andExpect(
            jsonPath("$.cause", is("The Region identified by name (unknown) could not be found!")));
  }

  @Test
  @WithMockUser
  public void failGettingEntryWhenCacheLoaderFails() throws Exception {
    mockMvc.perform(get("/v1/empty/10")
        .with(POST_PROCESSOR))
        .andExpect(status().isInternalServerError())
        .andExpect(
            jsonPath("$.message",
                is("Server has encountered timeout error while processing this request!")));
  }

  @Test
  @WithMockUser
  public void putEntry() throws Exception {
    mockMvc.perform(put("/v1/orders/2")
        .content(jsonResources.get(ORDER2_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(header().string("Location", BASE_URL + "/orders/2"));

    mockMvc.perform(put("/v1/orders/2")
        .content(jsonResources.get(ORDER2_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(header().string("Location", BASE_URL + "/orders/2"));
  }

  @Test
  @WithMockUser
  public void failPutEntryWithInvalidJson() throws Exception {
    mockMvc.perform(put("/v1/orders/1")
        .content(jsonResources.get(MALFORMED_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isBadRequest())
        .andExpect(
            jsonPath("$.cause", is("Json doc specified is either not supported or invalid!")));
  }

  @Test
  @WithMockUser
  public void failPutEntryWithInvalidRegion() throws Exception {
    mockMvc.perform(put("/v1/unknown/1")
        .content(jsonResources.get(ORDER1_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound())
        .andExpect(
            jsonPath("$.cause", is("The Region identified by name (unknown) could not be found!")));
  }

  @Test
  @WithMockUser
  public void failPutEntryOnRegionWhenCacheWriterFails() throws Exception {
    mockMvc.perform(put("/v1/empty/1")
        .content(jsonResources.get(ORDER1_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isInternalServerError())
        .andExpect(
            jsonPath("$.message",
                is("Server has encountered CacheWriter error while processing this request!")));
  }

  @Test
  @WithMockUser
  public void putAll() throws Exception {
    mockMvc.perform(
        put("/v1/customers/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60")
            .content(jsonResources.get(CUSTOMER_LIST_JSON))
            .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(header().string("Location", BASE_URL
            + "/customers/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60"));
  }

  @Test
  @WithMockUser
  public void failPutAllWithInvalidJson() throws Exception {
    mockMvc.perform(put("/v1/customers/1,2,3,4")
        .content(jsonResources.get(MALFORMED_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isBadRequest())
        .andExpect(jsonPath("$.cause", is("JSON document specified in the request is incorrect")));
  }

  @Test
  @WithMockUser
  public void failPutAllWithInvalidRegion() throws Exception {
    mockMvc.perform(
        put("/v1/unknown/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60")
            .content(jsonResources.get(CUSTOMER_LIST_JSON))
            .with(POST_PROCESSOR))
        .andExpect(status().isNotFound())
        .andExpect(
            jsonPath("$.cause", is("The Region identified by name (unknown) could not be found!")));
  }

  @Test
  @WithMockUser
  public void failPutAllWhenCacheWriterFails() throws Exception {
    mockMvc.perform(
        put("/v1/empty/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60")
            .content(jsonResources.get(CUSTOMER_LIST_JSON))
            .with(POST_PROCESSOR))
        .andExpect(status().isInternalServerError())
        .andExpect(
            jsonPath("$.cause", is("Put request failed as gemfire has thrown an error.")));
  }

  @Test
  @WithMockUser
  public void putWithReplace() throws Exception {
    // First time through the key does not exist and we get a 404
    mockMvc.perform(put("/v1/orders/2?op=REPLACE")
        .content(jsonResources.get(ORDER2_UPDATED_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound());

    // Create an entry that we can subsequently update
    mockMvc.perform(put("/v1/orders/2")
        .content(jsonResources.get(ORDER2_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(header().string("Location", BASE_URL
            + "/orders/2"));

    // Do the actual update
    mockMvc.perform(put("/v1/orders/2?op=REPLACE")
        .content(jsonResources.get(ORDER2_UPDATED_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(header().string("Location", BASE_URL
            + "/orders/2"));

    // Check the updated value
    mockMvc.perform(get("/v1/orders/2")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(content().json(jsonResources.get(ORDER2_UPDATED_JSON)));
  }

  @Test
  @WithMockUser
  public void failPutWithReplaceWithInvalidJson() throws Exception {
    mockMvc.perform(put("/v1/orders/1?op=REPLACE")
        .content(jsonResources.get(MALFORMED_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isBadRequest())
        .andExpect(
            jsonPath("$.cause", is("Json doc specified is either not supported or invalid!")));
  }

  @Test
  @WithMockUser
  public void failPutWithReplaceWithInvalidRegion() throws Exception {
    mockMvc.perform(put("/v1/unknown/1?op=REPLACE")
        .content(jsonResources.get(ORDER1_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound())
        .andExpect(
            jsonPath("$.cause", is("The Region identified by name (unknown) could not be found!")));
  }

  @Test
  @WithMockUser
  public void failPutWithReplaceFailsOnEmptyRegion() throws Exception {
    mockMvc.perform(put("/v1/empty/10?op=REPLACE")
        .content(jsonResources.get(ORDER1_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isInternalServerError())
        .andExpect(
            jsonPath("$.message",
                is("Resource (empty) configuration does not support the requested operation!")));
  }

  @Test
  @WithMockUser
  public void putWithCas() throws Exception {
    // First time through the key does not exist and we get a 404
    mockMvc.perform(put("/v1/orders/3?op=CAS")
        .content(jsonResources.get(ORDER_CAS_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isOk()) // This is wrong!!!
        .andExpect(header().string("Location", BASE_URL
            + "/orders/3"));

    // Create an entry that we can subsequently update
    mockMvc.perform(put("/v1/orders/3")
        .content(jsonResources.get(ORDER_CAS_OLD_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(header().string("Location", BASE_URL
            + "/orders/3"));

    // Check the value
    mockMvc.perform(get("/v1/orders/3")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(content().json(jsonResources.get(ORDER_CAS_OLD_JSON)));

    // Try and update with an incorrect old value
    mockMvc.perform(put("/v1/orders/3?op=CAS")
        .content(jsonResources.get(ORDER_CAS_WRONG_OLD_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isConflict())
        .andExpect(header().string("Location", BASE_URL
            + "/orders/3"))
        .andExpect(content().json(jsonResources.get(ORDER_CAS_OLD_JSON)));

    // Check that the value has not changed
    mockMvc.perform(get("/v1/orders/3")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(content().json(jsonResources.get(ORDER_CAS_OLD_JSON)));

    // Do the actual update
    mockMvc.perform(put("/v1/orders/3?op=CAS")
        .content(jsonResources.get(ORDER_CAS_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(header().string("Location", BASE_URL + "/orders/3"));

    // Check the updated value
    mockMvc.perform(get("/v1/orders/3")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(content().json(jsonResources.get(ORDER_CAS_NEW_JSON)));
  }

  @Test
  @WithMockUser
  public void failPutWithCasWithInvalidJson() throws Exception {
    mockMvc.perform(put("/v1/orders/1?op=CAS")
        .content(jsonResources.get(MALFORMED_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isBadRequest())
        .andExpect(
            jsonPath("$.cause", is("Json doc specified in request body is invalid!")));
  }

  @Test
  @WithMockUser
  public void failPutWithCasWithInvalidRegion() throws Exception {
    mockMvc.perform(put("/v1/unknown/10?op=CAS")
        .content(jsonResources.get(ORDER_CAS_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound())
        .andExpect(
            jsonPath("$.cause", is("The Region identified by name (unknown) could not be found!")));
  }

  @Test
  @WithMockUser
  public void failPutWithCasFailsOnEmptyRegion() throws Exception {
    mockMvc.perform(put("/v1/empty/10?op=CAS")
        .content(jsonResources.get(ORDER_CAS_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isInternalServerError())
        .andExpect(
            jsonPath("$.message",
                is("Resource (empty) configuration does not support the requested operation!")));
  }

  @Test
  @WithMockUser
  public void getRegions() throws Exception {
    mockMvc.perform(get("/v1")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(
            jsonPath("$.regions[*].name", containsInAnyOrder("customers", "orders", "empty")))
        .andExpect(
            jsonPath("$.regions[*].type", containsInAnyOrder("REPLICATE", "REPLICATE", "EMPTY")));
  }

  @Test
  @WithMockUser
  public void postRegions() throws Exception {
    mockMvc.perform(post("/v1")
        .with(POST_PROCESSOR))
        .andExpect(status().isMethodNotAllowed())
        .andExpect(jsonPath("$.cause", is("Request method 'POST' not supported")));
  }

  @Test
  @WithMockUser
  public void getCustomers() throws Exception {
    putAll();
    mockMvc.perform(get("/v1/customers?limit=ALL")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.customers", jsonEquals(jsonResources.get(CUSTOMER_LIST_JSON))));
  }

  @Test
  @WithMockUser
  public void getFromInvalidRegion() throws Exception {
    putAll();
    mockMvc.perform(get("/v1/unknown")
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound())
        .andExpect(
            jsonPath("$.cause", is("The Region identified by name (unknown) could not be found!")));
  }

  @Test
  @WithMockUser
  public void getCustomersWithLimit() throws Exception {
    putAll();
    mockMvc.perform(get("/v1/customers?limit=10")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.customers.length()", is(10)));
  }

  @Test
  @WithMockUser
  public void getAllKeys() throws Exception {
    putAll();
    mockMvc.perform(get("/v1/customers/keys")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.keys",
            containsInAnyOrder(IntStream.rangeClosed(1, 60).mapToObj(i -> i + "").toArray())));
  }

  @Test
  @WithMockUser
  public void getAllKeysFromInvalidRegion() throws Exception {
    mockMvc.perform(get("/v1/unknown/keys")
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound())
        .andExpect(
            jsonPath("$.cause", is("The Region identified by name (unknown) could not be found!")));
  }

  @Test
  @WithMockUser
  public void failPostAllKeys() throws Exception {
    mockMvc.perform(post("/v1/unknown/keys")
        .with(POST_PROCESSOR))
        .andExpect(status().isMethodNotAllowed())
        .andExpect(jsonPath("$.cause", is("Request method 'POST' not supported")));
  }

  @Test
  @WithMockUser
  public void getSpecificKeys() throws Exception {
    putAll();
    mockMvc.perform(get("/v1/customers/1,2,3,4,5")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(
            jsonPath("$.customers[*].customerId", containsInAnyOrder(101, 102, 103, 104, 105)));
  }

  @Test
  @WithMockUser
  public void getSpecificKeysFromUnknownRegion() throws Exception {
    mockMvc.perform(get("/v1/unknown/1,2,3,4,5")
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound())
        .andExpect(
            jsonPath("$.cause", is("The Region identified by name (unknown) could not be found!")));
  }

  @Test
  @WithMockUser
  public void deleteSingleKey() throws Exception {
    putAll();
    mockMvc.perform(delete("/v1/customers/1")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk());
  }

  @Test
  @WithMockUser
  public void deleteFromInvalidRegion() throws Exception {
    mockMvc.perform(delete("/v1/unknown/1")
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound());
  }

  @Test
  @WithMockUser
  public void deleteMultipleKeys() throws Exception {
    putAll();
    mockMvc.perform(delete("/v1/customers/2,3,4,5")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk());
  }

  @Test
  @WithMockUser
  public void deleteAllKeys() throws Exception {
    putAll();
    mockMvc.perform(delete("/v1/customers")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk());

    mockMvc.perform(head("/v1/customers")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(header().string("Resource-Count", "0"));
  }

  @Test
  @WithMockUser
  public void deleteMultipleKeysFromInvalidRegion() throws Exception {
    mockMvc.perform(delete("/v1/unknown/2,3,4,5")
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound());
  }

  @Test
  @WithMockUser
  public void deleteMultipleKeysFromEmptyRegion() throws Exception {
    mockMvc.perform(delete("/v1/empty/2,3,4,5")
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound());
  }

  @Test
  @WithMockUser
  public void createQueries() throws Exception {
    deleteAllQueries();

    mockMvc.perform(post(
        "/v1/queries?id=selectOrder&q=SELECT DISTINCT o FROM /orders o, o.items item WHERE item.quantity > $1 AND item.totalPrice > $2")
            .with(POST_PROCESSOR))
        .andExpect(status().isCreated())
        .andExpect(header().string("Location", BASE_URL + "/queries/selectOrder"));

    mockMvc.perform(
        post("/v1/queries?id=selectCustomer&q=SELECT c FROM /customers c WHERE c.customerId = $1")
            .with(POST_PROCESSOR))
        .andExpect(status().isCreated())
        .andExpect(header().string("Location", BASE_URL + "/queries/selectCustomer"));

    mockMvc.perform(post(
        "/v1/queries?id=selectHighRoller&q=SELECT DISTINCT c FROM /customers c, /orders o, o.items item WHERE item.totalprice > $1 AND c.customerId = o.customerId")
            .with(POST_PROCESSOR))
        .andExpect(status().isCreated())
        .andExpect(header().string("Location", BASE_URL + "/queries/selectHighRoller"));

    mockMvc.perform(get("/v1/queries")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(
            jsonPath("$.queries[*].id",
                containsInAnyOrder("selectOrder", "selectCustomer", "selectHighRoller")));
  }

  @Test
  @WithMockUser
  public void executeQueryWithParams() throws Exception {
    String QUERY_ARGS =
        "[{\"@type\": \"int\", \"@value\": 2}, {\"@type\": \"double\", \"@value\": 150.00}]";

    postEntry(); // order 1
    putEntry(); // order 2
    createQueries();
    mockMvc.perform(post("/v1/queries/selectOrder")
        .with(POST_PROCESSOR)
        .content(QUERY_ARGS))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.[0]", jsonEquals(jsonResources.get(ORDER1_NO_TYPE_JSON))));
  }

  @Test
  @WithMockUser
  public void executeAdhocQuery() throws Exception {
    putAll();
    mockMvc.perform(get("/v1/queries/adhoc?q=SELECT * FROM /customers LIMIT 100")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(content().json(jsonResources.get(CUSTOMER_LIST_NO_TYPE_JSON)));
  }

  @Test
  @WithMockUser
  public void putAndUpdateQuery() throws Exception {
    final String QUERY_ARGS = "[{\"@type\": \"int\", \"@value\": 20},"
        + "{\"@type\": \"int\", \"@value\": 120},"
        + "{\"@type\": \"int\", \"@value\": 130}]";

    deleteAllQueries();
    putAll(); // Create customers
    mockMvc.perform(
        post("/v1/queries?id=testQuery&q=SELECT DISTINCT c from /customers c where lastName=$1")
            .with(POST_PROCESSOR))
        .andExpect(status().isCreated())
        .andExpect(header().string("Location", BASE_URL + "/queries/testQuery"));

    mockMvc.perform(
        put("/v1/queries/testQuery?q=SELECT DISTINCT c from /customers c where customerId IN SET ($1, $2, $3)")
            .with(POST_PROCESSOR))
        .andExpect(status().isOk());

    mockMvc.perform(post("/v1/queries/testQuery")
        .content(QUERY_ARGS)
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.[*].customerId", containsInAnyOrder(120, 130)))
        .andExpect(jsonPath("$.[*].firstName", containsInAnyOrder("Preeti", "Varun")))
        .andExpect(jsonPath("$.[*].lastName", containsInAnyOrder("Kumari", "Agrawal")));
  }

  @Test
  @WithMockUser
  public void deleteQuery() throws Exception {
    mockMvc.perform(
        post("/v1/queries?id=myQuery&q=SELECT DISTINCT c from /customers c where lastName=$1")
            .with(POST_PROCESSOR))
        .andExpect(status().isCreated())
        .andExpect(header().string("Location", BASE_URL + "/queries/myQuery"));

    mockMvc.perform(delete("/v1/queries/myQuery")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk());

    mockMvc.perform(get("/v1/queries/myQuery")
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound());

    mockMvc.perform(delete("/v1/queries/myQuery")
        .with(POST_PROCESSOR))
        .andExpect(status().isNotFound());
  }

  @Test
  @WithMockUser
  public void putUnknownQuery() throws Exception {
    mockMvc.perform(
        put("/v1/queries/unknown?q=SELECT DISTINCT c from /customers c where customerId IN SET ($1, $2, $3)")
            .with(POST_PROCESSOR))
        .andExpect(status().isNotFound());
  }

  @Test
  @WithMockUser
  public void createQueryFromRequestBody() throws Exception {
    deleteAllQueries();

    mockMvc.perform(post("/v1/queries?id=testQuery")
        .content("SELECT * from /customers")
        .with(POST_PROCESSOR))
        .andExpect(status().isCreated())
        .andExpect(header().string("Location", BASE_URL + "/queries/testQuery"));

    mockMvc.perform(get("/v1/queries")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.queries[*].id", containsInAnyOrder("testQuery")))
        .andExpect(jsonPath("$.queries[*].oql", containsInAnyOrder("SELECT * from /customers")));

    mockMvc.perform(put("/v1/queries/testQuery")
        .content("SELECT * from /orders")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk());

    mockMvc.perform(get("/v1/queries")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.queries[*].id", containsInAnyOrder("testQuery")))
        .andExpect(jsonPath("$.queries[*].oql", containsInAnyOrder("SELECT * from /orders")));
  }

  @Test
  @WithMockUser
  public void listFunctions() throws Exception {
    mockMvc.perform(get("/v1/functions"))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.functions",
            containsInAnyOrder("AddFreeItemToOrders", "EchoArgumentFunction")));
  }

  @Test
  @WithMockUser
  public void executeFunction() throws Exception {
    final String FUNCTION_ARGS = "[{\"@type\": \"double\", \"@value\": 210},"
        + "{\"@type\": \"org.apache.geode.rest.internal.web.controllers.Item\","
        + "\"itemNo\": 599, \"description\": \"Part X Free on Bumper Offer\","
        + "\"quantity\": 2, \"unitprice\": 5, \"totalprice\": 10.00}]";

    putEntry(); // order 2
    mockMvc.perform(post("/v1/functions/AddFreeItemToOrders?onRegion=orders")
        .content(FUNCTION_ARGS)
        .with(POST_PROCESSOR))
        .andExpect(status().isOk());

    mockMvc.perform(get("/v1/orders/2")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.items[*].itemNo", containsInAnyOrder(1, 2, 599)))
        .andExpect(jsonPath("$.items[*].description",
            containsInAnyOrder("Product-3", "Product-4", "Part X Free on Bumper Offer")));
  }

  @Test
  @WithMockUser
  public void executeNoArgFunctionWithInvalidArg() throws Exception {
    mockMvc.perform(post("/v1/functions/EchoArgumentFunction")
        .content("{\"type\": \"int\"}")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(content().json("[{}]"));
  }

  @Test
  @WithMockUser
  public void executeNoArgFunctionWithEmptyObject() throws Exception {
    mockMvc.perform(post("/v1/functions/EchoArgumentFunction")
        .content("[{ }]")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(content().json("[{}]"));
  }

  @Test
  @WithMockUser
  public void executeNoArgFunctionWithEmptyArray() throws Exception {
    mockMvc.perform(post("/v1/functions/EchoArgumentFunction")
        .content("[]")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(content().json("[[]]"));
  }

  @Test
  @WithMockUser
  public void executeNoArgFunctionWithNoContent() throws Exception {
    mockMvc.perform(post("/v1/functions/EchoArgumentFunction")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(content().json("[null]"));
  }

  @Test
  @WithMockUser
  public void getEntryAfterCreation() throws Exception {
    mockMvc.perform(post("/v1/orders?key=10")
        .content(jsonResources.get(ORDER1_JSON))
        .with(POST_PROCESSOR))
        .andExpect(status().isCreated());

    mockMvc.perform(get("/v1/orders/10")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(content().json(jsonResources.get(ORDER1_JSON)));
  }

  @Test
  @WithMockUser
  public void getPing() throws Exception {
    mockMvc.perform(get("/v1/ping")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk());
  }

  @Test
  @WithMockUser
  public void headPing() throws Exception {
    mockMvc.perform(head("/v1/ping")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk());
  }

  @Test
  @WithMockUser
  public void headCustomers() throws Exception {
    putAll(); // load customers
    mockMvc.perform(head("/v1/customers")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andExpect(header().string("Resource-Count", "60"));
  }


  private void deleteAllQueries() throws Exception {
    MvcResult result = mockMvc.perform(get("/v1/queries")
        .with(POST_PROCESSOR))
        .andExpect(status().isOk())
        .andReturn();

    String content = result.getResponse().getContentAsString();
    List<String> ids = JsonPath.read(content, "$.queries[*].id");

    for (String id : ids) {
      mockMvc.perform(delete("/v1/queries/" + id)
          .with(POST_PROCESSOR))
          .andExpect(status().isOk());
    }
  }

  private static class StandardRequestPostProcessor implements RequestPostProcessor {
    @Override
    public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
      request.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
      request.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
      return request;
    }
  }

  static class SimpleCacheLoader implements CacheLoader, Declarable {
    @Override
    public Object load(LoaderHelper helper) {
      // throws TimeoutException
      throw new TimeoutException("Could not load entry. Request timed out.");
    }

    @Override
    public void close() {
      // nothing
    }

    @Override
    public void init(Properties props) {
      // nothing
    }
  }

  static class SimpleCacheWriter implements CacheWriter {
    @Override
    public void close() {
      // nothing
    }

    @Override
    public void beforeUpdate(EntryEvent event) throws CacheWriterException {
      // nothing
    }

    @Override
    public void beforeCreate(EntryEvent event) throws CacheWriterException {
      throw new CacheWriterException("Put request failed as gemfire has thrown an error.");
    }

    @Override
    public void beforeDestroy(EntryEvent event) throws CacheWriterException {
      throw new RegionDestroyedException("Region has already been destroyed.", "dummyRegion");
    }

    @Override
    public void beforeRegionDestroy(RegionEvent event) throws CacheWriterException {
      // nothing
    }

    @Override
    public void beforeRegionClear(RegionEvent event) throws CacheWriterException {
      // nothing
    }
  }
}


class TestContextLoader extends GenericXmlWebContextLoader {
  @Override
  protected void loadBeanDefinitions(GenericWebApplicationContext context,
      WebMergedContextConfiguration webMergedConfig) {
    super.loadBeanDefinitions(context, webMergedConfig);
    context.getServletContext().setAttribute(HttpService.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM,
        RestAccessControllerTest.rule.getCache().getSecurityService());
  }

}
