/*
 * 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.jcr.resource.internal.helper.jcr;


import java.util.ArrayList;
import java.util.List;

import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The {@code PathMapper} allows to
 * - map path from the JCR resource tree to resource paths
 * - hide JCR nodes; however this is not a security feature
 * @deprecated
 */
@Deprecated
@Designate(ocd = PathMapper.Config.class)
@Component(service = PathMapper.class,
           property = {
                   Constants.SERVICE_VENDOR + "=The Apache Software Foundation"
           })
public class PathMapper {

    @ObjectClassDefinition(name = "Apache Sling JCR Resource Provider Path Mapper",
        description = "This service provides path mappings for JCR nodes.")
    public @interface Config {

        @AttributeDefinition(name = "Path Mapping",
                description = "Defines an obtional path mapping for a path." +
                        "Each mapping entry is expressed as follow: <JCRPath>:<resourcePath>. As an example: /foo:/libs, " +
                        "this maps the JCR node /foo to the resource /libs. If the resource path is specified as '.', " +
                        " the JCR tree is not visible in the resource tree. This should not be considered a security feature " +
                        " as the nodes are still accessible through the JCR api. Mapping a JCR path to the root is not allowed. " +
                        "The mappings are evaluated as ordered in the configuration.")
        String[] path_mapping();
    }

    /** Logger */
    private final Logger log = LoggerFactory.getLogger(getClass());

    /** The mappings. */
    private final List<Mapping> mappings = new ArrayList<Mapping>();

    private static final class Mapping {
        public final String jcrPath;
        public final String resourcePath;
        public final String jcrPathPrefix;
        public final String resourcePathPrefix;

        public Mapping(final String path, final String mappedPath) {
            this.jcrPath = path;
            this.jcrPathPrefix = path.concat("/");
            if ( mappedPath.equals(".") ) {
                this.resourcePath = null;
                this.resourcePathPrefix = null;
            } else {
                this.resourcePath = mappedPath;
                this.resourcePathPrefix = mappedPath.concat("/");
            }
        }
    }

    @Activate
    private void activate(final Config configObj) {
        mappings.clear();
        final String[] config = configObj.path_mapping();
        if ( config != null ) {
            log.warn("The Apache Sling JCR Path Mapper is deprecated.");
            for (final String mapping : config) {
                boolean valid = false;
                final String[] parts = mapping.split(":");
                if (parts.length == 2) {
                    parts[0] = parts[0].trim();
                    parts[1] = parts[1].trim();
                    if ( parts[0].startsWith("/") && (parts[1].startsWith("/") || parts[1].equals(".")) ) {
                        if ( parts[0].endsWith("/") ) {
                            parts[0] = parts[0].substring(0, parts[1].length() - 1);
                        }
                        if ( parts[1].endsWith("/") ) {
                            parts[1] = parts[1].substring(0, parts[1].length() - 1);
                        }
                        if ( parts[0].length() > 1 && (parts[1].length() > 1 || parts[1].equals(".")) ) {
                            mappings.add(new Mapping(parts[0], parts[1]));
                            valid = true;
                        }
                    }
                }
                if ( !valid ) {
                    log.warn("Invalid mapping configuration (skipping): {}", mapping);
                }
            }
        }
    }

    /**
     * Map a resource path to a JCR path
     * @param resourcePath The resource path
     * @return The JCR path or {@code null}
     */
    public String mapResourcePathToJCRPath(final String resourcePath) {
        String jcrPath = resourcePath;
        if (resourcePath != null && !mappings.isEmpty()) {
            for (final Mapping mapping : mappings) {
                if ( mapping.resourcePath == null ) {
                    if ( resourcePath.equals(mapping.jcrPath) || resourcePath.startsWith(mapping.jcrPathPrefix) ) {
                        jcrPath = null;
                        break;
                    }
                } else {
                    if (resourcePath.equals(mapping.resourcePath)) {
                        jcrPath = mapping.jcrPath;
                        break;
                    } else if (resourcePath.startsWith(mapping.resourcePathPrefix)) {
                        jcrPath = mapping.jcrPathPrefix.concat(resourcePath.substring(mapping.resourcePathPrefix.length()));
                        break;
                    }
                }
            }
        }
        return jcrPath;
    }

    /**
     * Map a JCR path to a resource path
     * @param jcrPath The JCR path
     * @return The resource path or {@code null}
     */
    public String mapJCRPathToResourcePath(final String jcrPath) {
        String resourcePath = jcrPath;
        if (jcrPath != null && !mappings.isEmpty()) {
            for (final Mapping mapping : mappings) {
                if (mapping.resourcePath != null && (jcrPath.equals(mapping.resourcePath) || jcrPath.startsWith(mapping.resourcePathPrefix)) ) {
                    resourcePath = null;
                    break;
                } else if (jcrPath.equals(mapping.jcrPath)) {
                    resourcePath = mapping.resourcePath;
                    break;
                } else if (jcrPath.startsWith(mapping.jcrPathPrefix)) {
                    if ( mapping.resourcePath == null ) {
                        resourcePath = null;
                    } else {
                        resourcePath = mapping.resourcePathPrefix.concat(jcrPath.substring(mapping.jcrPathPrefix.length()));
                    }
                    break;
                }
            }
        }
        return resourcePath;
    }
}
