/*
 * 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.sling.testing.mock.sling;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.jcr.NamespaceRegistry;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.Workspace;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeDefinitionTemplate;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeDefinition;
import javax.jcr.nodetype.NodeTypeIterator;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.NodeTypeTemplate;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.nodetype.PropertyDefinitionTemplate;

import org.apache.jackrabbit.commons.cnd.CndImporter;
import org.apache.jackrabbit.commons.cnd.CompactNodeTypeDefReader;
import org.apache.jackrabbit.commons.cnd.DefinitionBuilderFactory;
import org.apache.jackrabbit.commons.cnd.TemplateBuilderFactory;
import org.apache.sling.testing.mock.osgi.ManifestScanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Singleton class that fetches all node type definitions from OSGi bundle MANIFEST.MF files
 * with "Sling-Nodetypes" definitions in the classpath.
 * Additionally it support registering them to a JCR repository.
 */
public final class NodeTypeDefinitionScanner {

    private static final NodeTypeDefinitionScanner SINGLETON = new NodeTypeDefinitionScanner();

    private static final int MAX_ITERATIONS = 5;

    private static final Logger log = LoggerFactory.getLogger(NodeTypeDefinitionScanner.class);

    private final List<String> nodeTypeDefinitions;

    private NodeTypeDefinitionScanner() {
        nodeTypeDefinitions = findeNodeTypeDefinitions();
    }

    /**
     * @return Node type definitions found in classpath as registered in OSGi bundle headers
     */
    public List<String> getNodeTypeDefinitions() {
        return nodeTypeDefinitions;
    }

    /**
     * Registers node types found in classpath in JCR repository.
     * @param session Session
     * @param nodeTypeMode Node type mode
     * @throws RepositoryException Repository exception
     */
    public void register(Session session, NodeTypeMode nodeTypeMode) throws RepositoryException {
      List<String> nodeTypeResources = getNodeTypeDefinitions();
      register(session, nodeTypeResources, nodeTypeMode);
    }

    /**
     * Registers node types found in classpath in JCR repository.
     * @param session Session
     * @param nodeTypeResources List of classpath resource URLs pointing to node type definitions
     * @param nodeTypeMode Node type mode
     * @throws RepositoryException Repository exception
     */
    public void register(Session session, List<String> nodeTypeResources, NodeTypeMode nodeTypeMode) throws RepositoryException {
      switch (nodeTypeMode) {
      case NOT_SUPPORTED:
          // do nothing
          break;
      case NAMESPACES_ONLY:
          registerNamespaces(session, nodeTypeResources);
          break;
      case NODETYPES_REQUIRED:
          registerNodeTypes(session, nodeTypeResources);
          break;
         default:
             throw new IllegalArgumentException("Node type mode not supported: " + nodeTypeMode);
      }
    }

    /**
     * Registers only the namespaces found in node type definitions in classpath in JCR repository.
     * @param session Session
     * @param nodeTypeResources List of classpath resource URLs pointing to node type definitions
     */
    private void registerNamespaces(Session session, List<String> nodeTypeResources) throws RepositoryException {
        ClassLoader classLoader = getClass().getClassLoader();
        Workspace workspace = session.getWorkspace();
        NamespaceRegistry namespaceRegistry = workspace.getNamespaceRegistry();
        ValueFactory valueFactory = session.getValueFactory();

      DefinitionBuilderFactory<NodeTypeTemplate, NamespaceRegistry> factory =
              new TemplateBuilderFactory(new DummyNodeTypeManager(), valueFactory, namespaceRegistry);

      for (String nodeTypeResource : nodeTypeResources) {
          try (InputStream is = classLoader.getResourceAsStream(nodeTypeResource)) {
              if (is == null) {
                  continue;
              }
              Reader reader = new InputStreamReader(is);
              CompactNodeTypeDefReader<NodeTypeTemplate, NamespaceRegistry> cndReader
                      = new CompactNodeTypeDefReader<NodeTypeTemplate, NamespaceRegistry>(reader, nodeTypeResource, factory);
              NamespaceRegistry mapping = cndReader.getNamespaceMapping();
              for (int i=0; i<mapping.getURIs().length; i++) {
                  String uri = mapping.getURIs()[i];
                  String prefix = mapping.getPrefix(uri);
                  try {
                      namespaceRegistry.registerNamespace(prefix, uri);
                  }
                  catch (RepositoryException ex) {
                      // ignore
                  }
              }
          }
          catch (Throwable ex) {
              log.warn("Unable to parse node type definition: " + nodeTypeResource, ex);
          }
      }

    }

    /**
     * Registers node types found in classpath in JCR repository.
     * @param session Session
     * @param nodeTypeResources List of classpath resource URLs pointing to node type definitions
     */
    private void registerNodeTypes(Session session, List<String> nodeTypeResources) throws RepositoryException {
      ClassLoader classLoader = getClass().getClassLoader();
      Workspace workspace = session.getWorkspace();
      NodeTypeManager nodeTypeManager = workspace.getNodeTypeManager();
      NamespaceRegistry namespaceRegistry = workspace.getNamespaceRegistry();
      ValueFactory valueFactory = session.getValueFactory();

      // try registering node types multiple times because the exact order is not known
      int iteration = 0;
      List<String> remainingNodeTypeResources = new ArrayList<String>(nodeTypeResources);
      while (!remainingNodeTypeResources.isEmpty()) {
          registerNodeTypesAndRemoveSucceeds(remainingNodeTypeResources, classLoader, nodeTypeManager, namespaceRegistry, valueFactory, false);
          iteration++;
          if (iteration >= MAX_ITERATIONS) {
              break;
          }
      }
      if (!remainingNodeTypeResources.isEmpty()) {
          registerNodeTypesAndRemoveSucceeds(remainingNodeTypeResources, classLoader, nodeTypeManager, namespaceRegistry, valueFactory, true);
      }
    }

    /**
     * Register node types found in classpath in JCR repository, and remove those that succeeded to register from the list.
     * @param nodeTypeResources List of nodetype classpath resources
     * @param classLoader
     * @param nodeTypeManager
     * @param namespaceRegistry
     * @param valueFactory
     * @param logError if true, and error is logged if node type registration failed. Otherwise it is ignored.
     */
    private void registerNodeTypesAndRemoveSucceeds(List<String> nodeTypeResources, ClassLoader classLoader,
            NodeTypeManager nodeTypeManager, NamespaceRegistry namespaceRegistry, ValueFactory valueFactory,
            boolean logError) {
        Iterator<String> nodeTypeResourcesIterator = nodeTypeResources.iterator();
        while (nodeTypeResourcesIterator.hasNext()) {
            String nodeTypeResource = nodeTypeResourcesIterator.next();
            try (InputStream is = classLoader.getResourceAsStream(nodeTypeResource)) {
                if (is == null) {
                    continue;
                }
                Reader reader = new InputStreamReader(is);
                CndImporter.registerNodeTypes(reader, nodeTypeResource, nodeTypeManager, namespaceRegistry, valueFactory, true);
                nodeTypeResourcesIterator.remove();
            }
            catch (Throwable ex) {
                if (logError) {
                    log.warn("Unable to register node type: " + nodeTypeResource, ex);
                }
            }
        }
    }

    /**
     * Find all node type definition classpath paths by searching all MANIFEST.MF files in the classpath and reading
     * the paths from the "Sling-Nodetypes" entry.
     * The order of the paths from each entry is preserved, but the overall order when multiple bundles define such an entry
     * is not deterministic and may not be correct according to the dependencies between the node type definitions.
     * @return List of node type definition class paths
     */
    private static List<String> findeNodeTypeDefinitions() {
        return new ArrayList<String>(ManifestScanner.getValues("Sling-Nodetypes"));
    }

    /**
     * @return Instance
     */
    public static NodeTypeDefinitionScanner get() {
        return SINGLETON;
    }


    /**
     * Some dummy classes to allow usage of CompactNodeTypeDefReader with underlying JCR mock
     */
    private static class DummyNodeTypeManager implements NodeTypeManager {
        @Override
        public NodeType getNodeType(String nodeTypeName) {
            return null;
        }
        @Override
        public boolean hasNodeType(String name) {
            return false;
        }
        @Override
        public NodeTypeIterator getAllNodeTypes() {
            return null;
        }
        @Override
        public NodeTypeIterator getPrimaryNodeTypes() {
            return null;
        }
        @Override
        public NodeTypeIterator getMixinNodeTypes() {
            return null;
        }
        @Override
        public NodeTypeTemplate createNodeTypeTemplate() {
            return new DummyNodeTypeTemplate();
        }
        @Override
        public NodeTypeTemplate createNodeTypeTemplate(NodeTypeDefinition ntd) {
            return new DummyNodeTypeTemplate();
        }
        @Override
        public NodeDefinitionTemplate createNodeDefinitionTemplate() {
            return new DummyNodeDefinitionTemplate();
        }
        @Override
        public PropertyDefinitionTemplate createPropertyDefinitionTemplate() {
            return new DummyPropertyDefinitionTemplate();
        }
        @Override
        public NodeType registerNodeType(NodeTypeDefinition ntd, boolean allowUpdate) {
            return null;
        }
        @Override
        public NodeTypeIterator registerNodeTypes(NodeTypeDefinition[] ntds, boolean allowUpdate) {
            return null;
        }
        @Override
        public void unregisterNodeType(String name) {
        }
        @Override
        public void unregisterNodeTypes(String[] names) {
        }
    }

    private static class DummyNodeTypeTemplate implements NodeTypeTemplate {
        @Override
        public String getName() {
            return null;
        }
        @Override
        public String[] getDeclaredSupertypeNames() {
            return null;
        }
        @Override
        public boolean isAbstract() {
            return false;
        }
        @Override
        public boolean isMixin() {
            return false;
        }
        @Override
        public boolean hasOrderableChildNodes() {
            return false;
        }
        @Override
        public boolean isQueryable() {
            return false;
        }
        @Override
        public String getPrimaryItemName() {
            return null;
        }
        @Override
        public PropertyDefinition[] getDeclaredPropertyDefinitions() {
            return null;
        }
        @Override
        public NodeDefinition[] getDeclaredChildNodeDefinitions() {
            return null;
        }
        @Override
        public void setName(String name) {
        }
        @Override
        public void setDeclaredSuperTypeNames(String[] names) {
        }
        @Override
        public void setAbstract(boolean abstractStatus) {
        }
        @Override
        public void setMixin(boolean mixin) {
        }
        @Override
        public void setOrderableChildNodes(boolean orderable) {
        }
        @Override
        public void setPrimaryItemName(String name) {
        }
        @Override
        public void setQueryable(boolean queryable) {
        }
        @Override
        public List getPropertyDefinitionTemplates() {
            return new ArrayList();
        }
        @Override
        public List getNodeDefinitionTemplates() {
            return new ArrayList();
        }
    }

    private static class DummyNodeDefinitionTemplate implements NodeDefinitionTemplate {
        @Override
        public NodeType[] getRequiredPrimaryTypes() {
            return null;
        }
        @Override
        public String[] getRequiredPrimaryTypeNames() {
            return null;
        }
        @Override
        public NodeType getDefaultPrimaryType() {
            return null;
        }
        @Override
        public String getDefaultPrimaryTypeName() {
            return null;
        }
        @Override
        public boolean allowsSameNameSiblings() {
            return false;
        }
        @Override
        public NodeType getDeclaringNodeType() {
            return null;
        }
        @Override
        public String getName() {
            return null;
        }
        @Override
        public boolean isAutoCreated() {
            return false;
        }
        @Override
        public boolean isMandatory() {
            return false;
        }
        @Override
        public int getOnParentVersion() {
            return 0;
        }
        @Override
        public boolean isProtected() {
            return false;
        }
        @Override
        public void setName(String name) {
        }
        @Override
        public void setAutoCreated(boolean autoCreated) {
        }
        @Override
        public void setMandatory(boolean mandatory) {
        }
        @Override
        public void setOnParentVersion(int opv) {
        }
        @Override
        public void setProtected(boolean protectedStatus) {
        }
        @Override
        public void setRequiredPrimaryTypeNames(String[] names) {
        }
        @Override
        public void setDefaultPrimaryTypeName(String name) {
        }
        @Override
        public void setSameNameSiblings(boolean allowSameNameSiblings) {
        }
    }

    private static class DummyPropertyDefinitionTemplate implements PropertyDefinitionTemplate {
        @Override
        public int getRequiredType() {
            return 0;
        }
        @Override
        public String[] getValueConstraints() {
            return null;
        }
        @Override
        public Value[] getDefaultValues() {
            return null;
        }
        @Override
        public boolean isMultiple() {
            return false;
        }
        @Override
        public String[] getAvailableQueryOperators() {
            return null;
        }
        @Override
        public boolean isFullTextSearchable() {
            return false;
        }
        @Override
        public boolean isQueryOrderable() {
            return false;
        }
        @Override
        public NodeType getDeclaringNodeType() {
            return null;
        }
        @Override
        public String getName() {
            return null;
        }
        @Override
        public boolean isAutoCreated() {
            return false;
        }
        @Override
        public boolean isMandatory() {
            return false;
        }
        @Override
        public int getOnParentVersion() {
            return 0;
        }
        @Override
        public boolean isProtected() {
            return false;
        }
        @Override
        public void setName(String name) {
        }
        @Override
        public void setAutoCreated(boolean autoCreated) {
        }
        @Override
        public void setMandatory(boolean mandatory) {
        }
        @Override
        public void setOnParentVersion(int opv) {
        }
        @Override
        public void setProtected(boolean protectedStatus) {
        }
        @Override
        public void setRequiredType(int type) {
        }
        @Override
        public void setValueConstraints(String[] constraints) {
        }
        @Override
        public void setDefaultValues(Value[] defaultValues) {
        }
        @Override
        public void setMultiple(boolean multiple) {
        }
        @Override
        public void setAvailableQueryOperators(String[] operators) {
        }
        @Override
        public void setFullTextSearchable(boolean fullTextSearchable) {
        }
        @Override
        public void setQueryOrderable(boolean queryOrderable) {
        }
    }

}
