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

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.util.List;
import java.util.Set;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.RestoreSystemProperties;

import org.apache.geode.cache.configuration.CacheConfig;
import org.apache.geode.cache.configuration.CacheElement;
import org.apache.geode.cache.configuration.GatewayReceiverConfig;
import org.apache.geode.cache.configuration.RegionConfig;
import org.apache.geode.cache.configuration.RegionType;
import org.apache.geode.internal.lang.SystemPropertyHelper;

public class JAXBServiceTest {

  private String xml;
  private CacheConfig unmarshalled;
  private JAXBService service;
  private JAXBService service2;

  @Rule
  public RestoreSystemProperties restore = new RestoreSystemProperties();

  @Before
  public void setUp() {
    service = new JAXBService(CacheConfig.class, ElementOne.class, ElementTwo.class);
    service.validateWithLocalCacheXSD();

    service2 = new JAXBService(CacheConfig.class);
    service2.validateWithLocalCacheXSD();
  }

  @Test
  public void getPackagesToScanWithoutSystemProperty() {
    Set<String> packages = JAXBService.getPackagesToScan();
    assertThat(packages).containsExactly("*");
  }

  @Test
  public void getPackagesToScanWithSystemProperty() {
    System.setProperty("geode." + SystemPropertyHelper.PACKAGES_TO_SCAN,
        "org.apache.geode,io.pivotal");
    Set<String> packages = JAXBService.getPackagesToScan();
    assertThat(packages).containsExactly("org.apache.geode", "io.pivotal");
  }

  @Test
  public void testCacheMarshall() {
    CacheConfig cacheConfig = new CacheConfig();
    setBasicValues(cacheConfig);

    xml = service.marshall(cacheConfig);
    System.out.println(xml);
    // cache has the default namespace
    assertThat(xml).contains("xmlns=\"http://geode.apache.org/schema/cache\"");
    assertThat(xml).contains(
        "xsi:schemaLocation=\"http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd\"");
    assertThat(xml).contains("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
    assertThat(xml).contains("</cache>");

    unmarshalled = service.unMarshall(xml);
  }

  @Test
  public void invalidXmlShouldFail() {
    CacheConfig cacheConfig = new CacheConfig();
    // missing version attribute
    assertThatThrownBy(() -> service.marshall(cacheConfig))
        .hasStackTraceContaining("Attribute 'version' must appear on element 'cache'");
  }

  @Test
  public void testCacheOneMarshall() {
    CacheConfig cache = new CacheConfig();
    setBasicValues(cache);
    cache.getCustomCacheElements().add(new ElementOne("test"));

    xml = service.marshall(cache);
    System.out.println(xml);
    // cache has the default namespace
    assertThat(xml).contains("xmlns=\"http://geode.apache.org/schema/cache\"");
    assertThat(xml).contains("custom-one>");
  }

  @Test
  public void testMixMarshall() {
    CacheConfig cache = new CacheConfig();
    setBasicValues(cache);
    cache.getCustomCacheElements().add(new ElementOne("testOne"));

    xml = service.marshall(cache);
    System.out.println(xml);
    assertThat(xml).contains("custom-one>");

    unmarshalled = service2.unMarshall(xml);
    unmarshalled.getCustomCacheElements().add(new ElementTwo("testTwo"));

    // xml generated wtih CacheConfigTwo has both elements in there.
    xml = service.marshall(unmarshalled);
    System.out.println(xml);
    assertThat(xml).contains("custom-one>");
    assertThat(xml).contains("custom-two>");
    assertThat(xml).containsPattern("xmlns=\"http://geode.apache.org/schema/cache\"");
    assertThat(xml).containsPattern("xmlns:ns\\d=\"http://geode.apache.org/schema/CustomOne\"");
    assertThat(xml).containsPattern("xmlns:ns\\d=\"http://geode.apache.org/schema/CustomTwo\"");
  }

  @Test
  public void xmlWithCustomElementsCanBeUnMarshalledByAnotherService() {
    CacheConfig cache = new CacheConfig();
    setBasicValues(cache);
    cache.getCustomCacheElements().add(new ElementOne("test"));
    cache.getCustomCacheElements().add(new ElementTwo("test"));

    String prettyXml = service.marshall(cache);
    System.out.println(prettyXml);

    CacheConfig cacheConfig = service2.unMarshall(prettyXml);
    List elements = cacheConfig.getCustomCacheElements();
    assertThat(elements.get(0)).isNotInstanceOf(ElementOne.class);
    assertThat(elements.get(1)).isNotInstanceOf(ElementTwo.class);

    String uglyXml = service2.marshall(cacheConfig);
    System.out.println(uglyXml);
    assertThat(uglyXml).isNotEqualTo(prettyXml);

    // the xml can be unmarshalled correctly by the first service
    String newXml = service.marshall(service.unMarshall(uglyXml));
    assertThat(newXml).isEqualTo(prettyXml);
  }

  @Test
  public void unmarshallPartialElement() {
    String xml = "<region name=\"one\">\n"
        + "        <region-attributes scope=\"distributed-ack\" data-policy=\"replicate\"/>\n"
        + "    </region>";

    RegionConfig config = service2.unMarshall(xml, RegionConfig.class);
    assertThat(config.getName()).isEqualTo("one");
  }

  @Test
  public void unmarshallAnyElement() {
    String xml = "<region name=\"one\">\n"
        + "        <region-attributes scope=\"distributed-ack\" data-policy=\"replicate\"/>\n"
        + "        <custom:any xmlns:custom=\"http://geode.apache.org/schema/custom\" id=\"any\"/>"
        + "    </region>";

    RegionConfig config = service2.unMarshall(xml, RegionConfig.class);
    assertThat(config.getName()).isEqualTo("one");
    assertThat(config.getCustomRegionElements()).hasSize(1);
  }

  @Test
  public void unmarshallIgnoresUnknownProperties() {
    // say xml has a type attribute that is removed in the new version
    String existingXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
        + "<cache version=\"1.0\" xsi:schemaLocation=\"http://geode.apache.org/schema/cache "
        + "http://geode.apache.org/schema/cache/cache-1.0.xsd\" "
        + "xmlns=\"http://geode.apache.org/schema/cache\" "
        + "xmlns:ns2=\"http://geode.apache.org/schema/CustomOne\" "
        + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" + "    <ns2:custom-one>\n"
        + "        <ns2:id>one</ns2:id>\n" + "        <ns2:type>onetype</ns2:type>\n"
        + "        <ns2:value>onevalue</ns2:value>\n" + "    </ns2:custom-one>\n" + "</cache>";

    CacheConfig cacheConfig = service.unMarshall(existingXML);
    List elements = cacheConfig.getCustomCacheElements();
    assertThat(elements.get(0)).isInstanceOf(ElementOne.class);
  }

  @Test
  public void marshalOlderNameSpace() {
    String xml =
        "<cache xsi:schemaLocation=\"http://schema.pivotal.io/gemfire/cache http://schema.pivotal.io/gemfire/cache/cache-8.1.xsd\"\n"
            +
            "       version=\"8.1\"\n" +
            "       xmlns=\"http://schema.pivotal.io/gemfire/cache\"\n" +
            "       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
            "    <region name=\"one\">\n" +
            "        <region-attributes scope=\"distributed-ack\" data-policy=\"replicate\"/>\n" +
            "    </region>\n" +
            "</cache>";

    CacheConfig cacheConfig = service2.unMarshall(xml);
    assertThat(cacheConfig.getRegions()).hasSize(1);
    assertThat(cacheConfig.getRegions().get(0).getName()).isEqualTo("one");
  }

  @Test
  public void marshallNoNameSpace() {
    String xml = "<cache version=\"1.0\">\n" +
        "    <region name=\"one\">\n" +
        "        <region-attributes scope=\"distributed-ack\" data-policy=\"replicate\"/>\n" +
        "    </region>\n" +
        "</cache>";

    CacheConfig cacheConfig = service2.unMarshall(xml);
    assertThat(cacheConfig.getRegions()).hasSize(1);
    assertThat(cacheConfig.getRegions().get(0).getName()).isEqualTo("one");
  }

  private void setBasicValues(CacheConfig cache) {
    GatewayReceiverConfig receiver = new GatewayReceiverConfig();
    receiver.setBindAddress("localhost");
    receiver.setEndPort("8080");
    receiver.setManualStart(false);
    receiver.setStartPort("6000");

    RegionConfig region = new RegionConfig();
    region.setName("testRegion");
    region.setType(RegionType.REPLICATE);

    cache.setCopyOnRead(true);
    cache.setGatewayReceiver(receiver);
    cache.setVersion("1.0");
    cache.getRegions().add(region);
  }

  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlType(name = "", propOrder = {"id", "value"})
  @XmlRootElement(name = "custom-one", namespace = "http://geode.apache.org/schema/CustomOne")
  public static class ElementOne extends CacheElement {
    @XmlElement(name = "id", namespace = "http://geode.apache.org/schema/CustomOne")
    private String id;
    @XmlElement(name = "value", namespace = "http://geode.apache.org/schema/CustomOne")
    private String value;

    public ElementOne() {
      // nothing
    }

    public String getValue() {
      return value;
    }

    public void setValue(String value) {
      this.value = value;
    }

    public ElementOne(String id) {
      this.id = id;
    }

    @Override
    public String getId() {
      return id;
    }

    public void setId(String value) {
      id = value;
    }
  }

  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlType(name = "", propOrder = {"id", "value"})
  @XmlRootElement(name = "custom-two", namespace = "http://geode.apache.org/schema/CustomTwo")
  public static class ElementTwo extends CacheElement {
    @XmlElement(name = "id", namespace = "http://geode.apache.org/schema/CustomTwo")
    private String id;
    @XmlElement(name = "value", namespace = "http://geode.apache.org/schema/CustomTwo")
    private String value;

    public ElementTwo() {
      // nothing
    }

    public String getValue() {
      return value;
    }

    public void setValue(String value) {
      this.value = value;
    }

    public ElementTwo(String id) {
      this.id = id;
    }

    @Override
    public String getId() {
      return id;
    }

    public void setId(String value) {
      id = value;
    }
  }

}
