/*
 * 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.management.internal.rest;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
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 org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.context.WebApplicationContext;

import org.apache.geode.management.api.ClusterManagementRealizationResult;
import org.apache.geode.management.api.ClusterManagementService;
import org.apache.geode.management.configuration.Region;

@RunWith(SpringRunner.class)
@ContextConfiguration(locations = {"classpath*:WEB-INF/management-servlet.xml"},
    loader = MockLocatorContextLoader.class)
@WebAppConfiguration
public class JsonSerializationTest {

  @Autowired
  private WebApplicationContext webApplicationContext;

  // needs to be used together with any LocatorContextLoader
  private LocatorWebContext context;

  private MockLocatorContextLoader mockLocator;
  private ClusterManagementService cms;

  private ArgumentCaptor<Region> regionConfigCaptor;

  @Before
  public void before() {
    context = new LocatorWebContext(webApplicationContext);
    regionConfigCaptor = ArgumentCaptor.forClass(Region.class);
    mockLocator = (MockLocatorContextLoader) context.getLocator();
    cms = mockLocator.getClusterManagementService();
  }

  @Test
  public void invalidAttributes() throws Exception {
    String json = "{'name':'test','Group1':'group1','Group2':'group2'}";
    when(cms.create(any())).thenReturn(new ClusterManagementRealizationResult());
    context.perform(post("/v1/regions").content(json))
        .andExpect(status().isBadRequest())
        .andExpect(jsonPath("$.statusCode", Matchers.is("ILLEGAL_ARGUMENT")))
        .andExpect(jsonPath("$.statusMessage",
            Matchers.containsString("JSON parse error: Unrecognized field \"Group1\"")))
        .andExpect(jsonPath("$.statusMessage", Matchers.not(Matchers.containsString("Group2"))));
  }

  @Test
  public void validAttributes() throws Exception {
    String json = "{'name':'test','group':'group1'}";
    when(cms.create(any())).thenReturn(new ClusterManagementRealizationResult());
    context.perform(post("/v1/regions").content(json))
        .andExpect(header().string("content-type", "application/json;charset=UTF-8"))
        .andExpect(status().isCreated());
    verify(cms, atLeastOnce()).create(regionConfigCaptor.capture());
    Region value = regionConfigCaptor.getValue();
    assertThat(value.getGroup()).isEqualTo("group1");
  }
}
