/*
 * 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.oak.restrictions.impl;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.AbstractRestrictionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionDefinition;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionDefinitionImpl;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionPattern;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Sling restriction provider implementation that supports the following restrictions:
 *
 * <ul>
 * <li>{@link #SLING_RESOURCE_TYPES}: A restriction that allows to match against resource types (matches are exact and do not include children).</li>
 * <li>{@link #SLING_RESOURCE_TYPES_WITH_DESCENDANTS}: A restriction that allows to match against resource types and all sub nodes of matching resource types.</li>
 * </ul>
 * 
 * Further sling restriction can be added here in future.
*/
@Component
@Service(RestrictionProvider.class)
public class SlingRestrictionProviderImpl extends AbstractRestrictionProvider {

    private static final Logger LOG = LoggerFactory.getLogger(SlingRestrictionProviderImpl.class);

    public static final String SLING_RESOURCE_TYPES = "sling:resourceTypes";
    public static final String SLING_RESOURCE_TYPES_WITH_DESCENDANTS = "sling:resourceTypesWithDescendants";

    public SlingRestrictionProviderImpl() {
        super(supportedRestrictions());
    }

    private static Map<String, RestrictionDefinition> supportedRestrictions() {
        RestrictionDefinition slingResourceTypes = new RestrictionDefinitionImpl(SLING_RESOURCE_TYPES, Type.STRINGS, false);
        RestrictionDefinition slingResourceTypesWithChildren = new RestrictionDefinitionImpl(SLING_RESOURCE_TYPES_WITH_DESCENDANTS, Type.STRINGS, false);
        Map<String, RestrictionDefinition> supportedRestrictions = new HashMap<String, RestrictionDefinition>();
        supportedRestrictions.put(slingResourceTypes.getName(), slingResourceTypes);
        supportedRestrictions.put(slingResourceTypesWithChildren.getName(), slingResourceTypesWithChildren);
        return Collections.unmodifiableMap(supportedRestrictions);
    }

    // ------------------------------------------------< RestrictionProvider >---

    @Nonnull
    @Override
    public RestrictionPattern getPattern(String oakPath, @Nonnull Tree tree) {
        if (oakPath != null) {
            PropertyState resourceTypes = tree.getProperty(SLING_RESOURCE_TYPES);
            if (resourceTypes != null) {
                ResourceTypePattern resourceTypePattern = new ResourceTypePattern(resourceTypes.getValue(Type.STRINGS), oakPath, false);
                LOG.trace("Returning resourceTypePattern={} for rep:slingResourceTypes in getPattern(String,Tree)", resourceTypePattern);
                return resourceTypePattern;
            }
            PropertyState resourceTypesWithChildren = tree.getProperty(SLING_RESOURCE_TYPES_WITH_DESCENDANTS);
            if (resourceTypesWithChildren != null) {
                ResourceTypePattern resourceTypePattern = new ResourceTypePattern(resourceTypesWithChildren.getValue(Type.STRINGS), oakPath, true);
                LOG.trace("Returning resourceTypePattern={} for rep:slingResourceTypesWithChildren in getPattern(String,Tree)", resourceTypePattern);
                return resourceTypePattern;
            }            
        }
        return RestrictionPattern.EMPTY;
    }

    @Nonnull
    @Override
    public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Set<Restriction> restrictions) {

        if (oakPath != null && !restrictions.isEmpty()) {
            for (Restriction r : restrictions) {
                String name = r.getDefinition().getName();
                if (SLING_RESOURCE_TYPES.equals(name)) {
                    ResourceTypePattern resourceTypePattern = new ResourceTypePattern(r.getProperty().getValue(Type.STRINGS), oakPath, false);
                    LOG.trace(
                            "Returning resourceTypePattern={} for rep:slingResourceTypes in getPattern(String,Set<Restriction>)",
                            resourceTypePattern);
                    return resourceTypePattern;
                } else if(SLING_RESOURCE_TYPES_WITH_DESCENDANTS.equals(name)) {
                    ResourceTypePattern resourceTypePattern = new ResourceTypePattern(r.getProperty().getValue(Type.STRINGS), oakPath, true);
                    LOG.trace(
                            "Returning resourceTypePattern={} for rep:slingResourceTypesWithChildren in getPattern(String,Set<Restriction>)",
                            resourceTypePattern);
                    return resourceTypePattern;
                }
            }
        }

        return RestrictionPattern.EMPTY;
    }

}