/*
 * 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.configuration.domain;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.xpath.XPathExpressionException;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import org.apache.geode.DataSerializer;
import org.apache.geode.InternalGemFireError;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.internal.Assert;
import org.apache.geode.internal.VersionedDataSerializable;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.cache.xmlcache.CacheXml;
import org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator;
import org.apache.geode.internal.serialization.Version;
import org.apache.geode.logging.internal.log4j.api.LogService;
import org.apache.geode.management.internal.configuration.utils.XmlUtils;
import org.apache.geode.management.internal.configuration.utils.XmlUtils.XPathContext;

/**
 * Domain class for defining a GemFire entity in XML.
 */
public class XmlEntity implements VersionedDataSerializable {
  private static final long serialVersionUID = 1L;
  private static final Logger logger = LogService.getLogger();

  private transient volatile CacheProvider cacheProvider;

  private String type;

  @SuppressWarnings("unused")
  private String parentType;

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

  private String xmlDefinition;

  private String searchString;

  private String prefix = CacheXml.PREFIX;

  private String namespace = CacheXml.GEODE_NAMESPACE;

  private String childPrefix;

  private String childNamespace;

  /**
   * Produce a new XmlEntityBuilder.
   *
   * @return new XmlEntityBuilder.
   * @since GemFire 8.1
   */
  public static XmlEntityBuilder builder() {
    return new XmlEntityBuilder();
  }

  private static CacheProvider createDefaultCacheProvider() {
    return () -> ((InternalCache) CacheFactory.getAnyInstance())
        .getCacheForProcessingClientRequests();
  }

  /**
   * Default constructor for serialization only.
   *
   * @deprecated Use {@link XmlEntity#builder()}.
   */
  @Deprecated
  public XmlEntity() {
    cacheProvider = createDefaultCacheProvider();
  }

  /**
   * Construct a new XmlEntity while creating XML from the cache using the element which has a type
   * and attribute matching those given.
   *
   * @param type Type of the XML element to search for. Should be one of the constants from the
   *        {@link CacheXml} class. For example, CacheXml.REGION.
   * @param key Key of the attribute to match, for example, "name" or "id".
   * @param value Value of the attribute to match.
   */
  public XmlEntity(final String type, final String key, final String value) {
    cacheProvider = createDefaultCacheProvider();
    this.type = type;
    attributes.put(key, value);

    init();
  }

  /**
   * Construct a new XmlEntity while creating Xml from the cache using the element which has
   * attributes matching those given
   *
   * @param parentType Parent type of the XML element to search for. Should be one of the constants
   *        from the {@link CacheXml} class. For example, CacheXml.REGION.
   *
   * @param parentKey Identifier for the parent elements such "name/id"
   * @param parentValue Value of the identifier
   * @param childType Child type of the XML element to search for within the parent . Should be one
   *        of the constants from the {@link CacheXml} class. For example, CacheXml.INDEX.
   * @param childKey Identifier for the child element such as "name/id"
   * @param childValue Value of the child element identifier
   */
  public XmlEntity(final String parentType, final String parentKey, final String parentValue,
      final String childType, final String childKey, final String childValue) {
    cacheProvider = createDefaultCacheProvider();
    this.parentType = parentType;
    type = childType;
    initializeSearchString(parentKey, parentValue, prefix, childKey, childValue);
  }

  /**
   * Construct a new XmlEntity while creating Xml from the cache using the element which has
   * attributes matching those given
   *
   * @param parentType Parent type of the XML element to search for. Should be one of the constants
   *        from the {@link CacheXml} class. For example, CacheXml.REGION.
   *
   * @param parentKey Identifier for the parent elements such "name/id"
   * @param parentValue Value of the identifier
   * @param childPrefix Namespace prefix for the child element such as "lucene"
   * @param childNamespace Namespace for the child element such as
   *        "http://geode.apache.org/schema/lucene"
   * @param childType Child type of the XML element to search for within the parent . Should be one
   *        of the constants from the {@link CacheXml} class. For example, CacheXml.INDEX.
   * @param childKey Identifier for the child element such as "name/id"
   * @param childValue Value of the child element identifier
   */
  public XmlEntity(final String parentType, final String parentKey, final String parentValue,
      final String childPrefix, final String childNamespace, final String childType,
      final String childKey, final String childValue) {
    // Note: Do not invoke init
    cacheProvider = createDefaultCacheProvider();
    this.parentType = parentType;
    type = childType;
    this.childPrefix = childPrefix;
    this.childNamespace = childNamespace;
    initializeSearchString(parentKey, parentValue, childPrefix, childKey, childValue);
  }

  public XmlEntity(final CacheProvider cacheProvider, final String parentType,
      final String childPrefix, final String childNamespace, final String childType,
      final String key, final String value) {
    this.cacheProvider = cacheProvider;
    this.parentType = parentType;
    type = childType;
    prefix = childPrefix;
    namespace = childNamespace;
    this.childPrefix = childPrefix;
    this.childNamespace = childNamespace;
    attributes.put(key, value);

    searchString = "//" + this.parentType + '/' + childPrefix + ':' + type;
    xmlDefinition = parseXmlForDefinition();
  }

  private String parseXmlForDefinition() {
    final Cache cache = cacheProvider.getCache();

    final StringWriter stringWriter = new StringWriter();
    final PrintWriter printWriter = new PrintWriter(stringWriter);
    CacheXmlGenerator.generate(cache, printWriter, false, false);
    printWriter.close();
    InputSource inputSource = new InputSource(new StringReader(stringWriter.toString()));

    try {
      Document document = XmlUtils.getDocumentBuilder().parse(inputSource);
      Node element = document.getElementsByTagNameNS(childNamespace, type).item(0);
      if (null != element) {
        return XmlUtils.elementToString(element);
      }
    } catch (IOException | ParserConfigurationException | RuntimeException | SAXException
        | TransformerException e) {
      throw new InternalGemFireError("Could not parse XML when creating XMLEntity", e);
    }

    logger.warn("No XML definition could be found with name={} and attributes={}", type,
        attributes);
    return null;
  }

  private void initializeSearchString(final String parentKey, final String parentValue,
      final String childPrefix, final String childKey, final String childValue) {
    StringBuilder sb = new StringBuilder();
    sb.append("//").append(prefix).append(':').append(parentType);

    if (StringUtils.isNotBlank(parentKey) && StringUtils.isNotBlank(parentValue)) {
      sb.append("[@").append(parentKey).append("='").append(parentValue).append("']");
    }

    sb.append('/').append(childPrefix).append(':').append(type);

    if (StringUtils.isNotBlank(childKey) && StringUtils.isNotBlank(childValue)) {
      sb.append("[@").append(childKey).append("='").append(childValue).append("']");
    }
    searchString = sb.toString();
  }

  /**
   * Initialize new instances. Called from {@link #XmlEntity(String, String, String)} and
   * {@link XmlEntityBuilder#build()}.
   *
   * @since GemFire 8.1
   */
  private void init() {
    Assert.assertTrue(StringUtils.isNotBlank(type));
    Assert.assertTrue(StringUtils.isNotBlank(prefix));
    Assert.assertTrue(StringUtils.isNotBlank(namespace));
    Assert.assertTrue(attributes != null);

    if (null == xmlDefinition) {
      xmlDefinition = loadXmlDefinition();
    }
  }

  /**
   * Use the CacheXmlGenerator to create XML from the entity associated with the current cache.
   *
   * @return XML string representation of the entity.
   */
  private String loadXmlDefinition() {
    final Cache cache = cacheProvider.getCache();

    final StringWriter stringWriter = new StringWriter();
    final PrintWriter printWriter = new PrintWriter(stringWriter);
    CacheXmlGenerator.generate(cache, printWriter, false, false);
    printWriter.close();

    return loadXmlDefinition(stringWriter.toString());
  }

  /**
   * Used supplied xmlDocument to extract the XML for the defined XmlEntity.
   *
   * @param xmlDocument to extract XML from.
   * @return XML for XmlEntity if found, otherwise {@code null}.
   * @since GemFire 8.1
   */
  private String loadXmlDefinition(final String xmlDocument) {
    try {
      InputSource inputSource = new InputSource(new StringReader(xmlDocument));
      return loadXmlDefinition(XmlUtils.getDocumentBuilder().parse(inputSource));
    } catch (IOException | SAXException | ParserConfigurationException | XPathExpressionException
        | TransformerFactoryConfigurationError | TransformerException e) {
      throw new InternalGemFireError("Could not parse XML when creating XMLEntity", e);
    }
  }

  /**
   * Used supplied XML {@link Document} to extract the XML for the defined XmlEntity.
   *
   * @param document to extract XML from.
   * @return XML for XmlEntity if found, otherwise {@code null}.
   * @since GemFire 8.1
   */
  private String loadXmlDefinition(final Document document)
      throws XPathExpressionException, TransformerFactoryConfigurationError, TransformerException {
    searchString = createQueryString(prefix, type, attributes);
    logger.info("XmlEntity:searchString: {}", searchString);

    if (document != null) {
      XPathContext xpathContext = new XPathContext();
      xpathContext.addNamespace(prefix, namespace);

      // TODO: wrap this line with conditional
      xpathContext.addNamespace(childPrefix, childNamespace);

      // Create an XPathContext here
      Node element = XmlUtils.querySingleElement(document, searchString, xpathContext);

      // Must copy to preserve namespaces.
      if (null != element) {
        return XmlUtils.elementToString(element);
      }
    }

    logger.warn("No XML definition could be found with name={} and attributes={}", type,
        attributes);
    return null;
  }

  /**
   * Create an XmlPath query string from the given element name and attributes.
   *
   * @param element Name of the XML element to search for.
   * @param attributes Attributes of the element that should match, for example "name" or "id" and
   *        the value they should equal. This list may be empty.
   *
   * @return An XmlPath query string.
   */
  private String createQueryString(final String prefix, final String element,
      final Map<String, String> attributes) {
    StringBuilder queryStringBuilder = new StringBuilder();
    Iterator<Entry<String, String>> attributeIter = attributes.entrySet().iterator();
    queryStringBuilder.append("//").append(prefix).append(':').append(element);

    if (!attributes.isEmpty()) {
      queryStringBuilder.append('[');
      Entry<String, String> attrEntry = attributeIter.next();
      queryStringBuilder.append('@').append(attrEntry.getKey()).append("='")
          .append(attrEntry.getValue()).append('\'');
      while (attributeIter.hasNext()) {
        attrEntry = attributeIter.next();
        queryStringBuilder.append(" and @").append(attrEntry.getKey()).append("='")
            .append(attrEntry.getValue()).append('\'');
      }

      queryStringBuilder.append(']');
    }

    return queryStringBuilder.toString();
  }

  public String getSearchString() {
    return searchString;
  }

  public String getType() {
    return type;
  }

  public Map<String, String> getAttributes() {
    return attributes;
  }

  /**
   * Return the value of a single attribute.
   *
   * @param key Key of the attribute whose while will be returned.
   *
   * @return The value of the attribute.
   */
  public String getAttribute(String key) {
    return attributes.get(key);
  }

  /**
   * A convenience method to get a name or id attributes from the list of attributes if one of them
   * has been set. Name takes precedence.
   *
   * @return The name or id attribute or null if neither is found.
   */
  public String getNameOrId() {
    if (attributes.containsKey("name")) {
      return attributes.get("name");
    }

    return attributes.get("id");
  }

  public String getXmlDefinition() {
    return xmlDefinition;
  }

  /**
   * Gets the namespace for the element. Defaults to {@link CacheXml#GEODE_NAMESPACE} if not set.
   *
   * @return XML element namespace
   * @since GemFire 8.1
   */
  public String getNamespace() {
    return namespace;
  }

  /**
   * Gets the prefix for the element. Defaults to {@link CacheXml#PREFIX} if not set.
   *
   * @return XML element prefix
   * @since GemFire 8.1
   */
  public String getPrefix() {
    return prefix;
  }

  /**
   * Gets the prefix for the child element.
   *
   * @return XML element prefix for the child element
   */
  public String getChildPrefix() {
    return childPrefix;
  }

  /**
   * Gets the namespace for the child element.
   *
   * @return XML element namespace for the child element
   */
  public String getChildNamespace() {
    return childNamespace;
  }

  @Override
  public Version[] getSerializationVersions() {
    return new Version[] {Version.GEODE_1_1_1};
  }

  @Override
  public String toString() {
    return "XmlEntity [namespace=" + namespace + ", type=" + type + ", attributes="
        + attributes + ", xmlDefinition=" + xmlDefinition + ']';
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((attributes == null) ? 0 : attributes.hashCode());
    result = prime * result + ((type == null) ? 0 : type.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    XmlEntity other = (XmlEntity) obj;
    if (attributes == null) {
      if (other.attributes != null)
        return false;
    } else if (!attributes.equals(other.attributes))
      return false;
    if (namespace == null) {
      if (other.namespace != null)
        return false;
    } else if (!namespace.equals(other.namespace))
      return false;
    if (type == null) {
      return other.type == null;
    } else
      return type.equals(other.type);
  }

  @Override
  public void toData(DataOutput out) throws IOException {
    toDataPre_GEODE_1_1_1_0(out);
    DataSerializer.writeString(childPrefix, out);
    DataSerializer.writeString(childNamespace, out);
  }

  public void toDataPre_GEODE_1_1_1_0(DataOutput out) throws IOException {
    DataSerializer.writeString(type, out);
    DataSerializer.writeObject(attributes, out);
    DataSerializer.writeString(xmlDefinition, out);
    DataSerializer.writeString(searchString, out);
    DataSerializer.writeString(prefix, out);
    DataSerializer.writeString(namespace, out);
  }

  @Override
  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
    fromDataPre_GEODE_1_1_1_0(in);
    childPrefix = DataSerializer.readString(in);
    childNamespace = DataSerializer.readString(in);
  }

  public void fromDataPre_GEODE_1_1_1_0(DataInput in) throws IOException, ClassNotFoundException {
    type = DataSerializer.readString(in);
    attributes = DataSerializer.readObject(in);
    xmlDefinition = DataSerializer.readString(in);
    searchString = DataSerializer.readString(in);
    prefix = DataSerializer.readString(in);
    namespace = DataSerializer.readString(in);
    cacheProvider = createDefaultCacheProvider();
  }

  /**
   * Defines how XmlEntity gets a reference to the Cache.
   */
  public interface CacheProvider {
    InternalCache getCache();
  }

  /**
   * Builder for XmlEntity. Default values are as described in XmlEntity.
   *
   * @since GemFire 8.1
   */
  public static class XmlEntityBuilder {

    private XmlEntity xmlEntity;

    /**
     * Private constructor.
     *
     * @since GemFire 8.1
     */
    @SuppressWarnings("deprecation")
    XmlEntityBuilder() {
      xmlEntity = new XmlEntity();
    }

    /**
     * Produce an XmlEntity with the supplied values. Builder is reset after #build() is called.
     * Subsequent calls will produce a new XmlEntity.
     *
     * You are required to at least call {@link #withType(String)}.
     *
     * @since GemFire 8.1
     */
    @SuppressWarnings("deprecation")
    public XmlEntity build() {
      xmlEntity.init();

      final XmlEntity built = xmlEntity;
      xmlEntity = new XmlEntity();

      return built;
    }

    /**
     * Sets the type or element name value as returned by {@link XmlEntity#getType()}
     *
     * @param type Name of element type.
     * @return this XmlEntityBuilder
     * @since GemFire 8.1
     */
    public XmlEntityBuilder withType(final String type) {
      xmlEntity.type = type;

      return this;
    }

    /**
     * Sets the element prefix and namespace as returned by {@link XmlEntity#getPrefix()} and
     * {@link XmlEntity#getNamespace()} respectively. Defaults are {@link CacheXml#PREFIX} and
     * {@link CacheXml#GEODE_NAMESPACE} respectively.
     *
     * @param prefix Prefix of element
     * @param namespace Namespace of element
     * @return this XmlEntityBuilder
     * @since GemFire 8.1
     */
    public XmlEntityBuilder withNamespace(final String prefix, final String namespace) {
      xmlEntity.prefix = prefix;
      xmlEntity.namespace = namespace;

      return this;
    }

    /**
     * Adds an attribute for the given <code>name</code> and <code>value</code> to the attributes
     * map returned by {@link XmlEntity#getAttributes()} or {@link XmlEntity#getAttribute(String)}.
     *
     * @param name Name of attribute to set.
     * @param value Value of attribute to set.
     * @return this XmlEntityBuilder
     * @since GemFire 8.1
     */
    public XmlEntityBuilder withAttribute(final String name, final String value) {
      xmlEntity.attributes.put(name, value);

      return this;
    }

    /**
     * Replaces all attributes with the supplied attributes {@link Map}.
     *
     * @param attributes {@link Map} to use.
     * @return this XmlEntityBuilder
     * @since GemFire 8.1
     */
    public XmlEntityBuilder withAttributes(final Map<String, String> attributes) {
      xmlEntity.attributes = attributes;

      return this;
    }

    /**
     * Sets a config xml document source to get the entity XML Definition from as returned by
     * {@link XmlEntity#getXmlDefinition()}. Defaults to current active configuration for
     * {@link Cache}.
     *
     * <b>Should only be used for testing.</b>
     *
     * @param document Config XML {@link Document}.
     * @return this XmlEntityBuilder
     * @since GemFire 8.1
     */
    public XmlEntityBuilder withConfig(final Document document) throws XPathExpressionException,
        TransformerFactoryConfigurationError, TransformerException {
      xmlEntity.xmlDefinition = xmlEntity.loadXmlDefinition(document);

      return this;
    }
  }
}
