/*
 * Copyright (c) 2008-2009 trialox.org (trialox AG, Switzerland).
 * 
 * Licensed 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.clerezza.platform.content;

import java.net.URL;
import java.util.Map;
import javax.ws.rs.GET;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.apache.clerezza.platform.content.WebDavUtils.PropertyMap;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.clerezza.platform.content.webdav.COPY;
import org.apache.clerezza.platform.content.webdav.LOCK;
import org.apache.clerezza.platform.content.webdav.UNLOCK;
import org.apache.clerezza.platform.typehandlerspace.SupportedTypes;
import org.apache.clerezza.platform.typerendering.RenderletManager;
import org.apache.clerezza.platform.typerendering.scalaserverpages.ScalaServerPagesRenderlet;
import org.apache.clerezza.commons.rdf.Graph;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.apache.clerezza.commons.rdf.IRI;
import org.apache.clerezza.commons.rdf.impl.utils.simple.SimpleGraph;
import org.apache.clerezza.rdf.ontologies.HIERARCHY;
import org.apache.clerezza.rdf.ontologies.PLATFORM;
import org.apache.clerezza.rdf.ontologies.RDF;
import org.apache.clerezza.rdf.utils.GraphNode;
import org.apache.clerezza.rdf.utils.UnionGraph;
import org.apache.felix.scr.annotations.Services;
import org.osgi.service.component.ComponentContext;

/**
 * Provides HTTP Methods for WebDav
 * 
 * @author ali
 */

@Component
@Services({
    @Service(Object.class),
    @Service(CollectionTypeHandler.class)
})
@Property(name = "org.apache.clerezza.platform.typehandler", boolValue = true)
@SupportedTypes(types = { "http://clerezza.org/2009/09/hierarchy#Collection" }, prioritize = true)
public class CollectionTypeHandler extends DiscobitsTypeHandler{

    private Logger logger = LoggerFactory.getLogger(CollectionTypeHandler.class);
    
    @Reference
    private RenderletManager renderletManager;

    /**
     * The activate method is called when SCR activates the component configuration.
     * This method gets the system graph or create a new one if it doesn't exist.
     *
     * @param componentContext
     */
    protected void activate(ComponentContext componentContext) {
        URL templateURL = getClass().getResource("collection.ssp");
        renderletManager.registerRenderlet(ScalaServerPagesRenderlet.class.getName(),
                new IRI(templateURL.toString()), HIERARCHY.Collection,
                "naked", MediaType.APPLICATION_XHTML_XML_TYPE, true);

        logger.info("CollectionTypeHandler activated.");
    }

    /**
     * Returns a GraphNode of the requested collection
     * @return 
     */
    @GET
    @Override
    public GraphNode getResource(@Context UriInfo uriInfo) {
        final Graph contentGraph = cgProvider.getContentGraph();
        final String uriString = uriInfo.getAbsolutePath().toString();
        final IRI indexUri = new IRI(uriString+"index");
        if (contentGraph.filter(indexUri, null, null).hasNext()) {
            return new GraphNode(indexUri, contentGraph);
        }
        final IRI uri = new IRI(uriString);
        Graph mGraph = new UnionGraph(new SimpleGraph(), contentGraph);
        final GraphNode graphNode = new GraphNode(uri, mGraph);
        graphNode.addProperty(RDF.type, PLATFORM.HeadedPage);

        IRI collectionUri = new IRI(uriInfo.getAbsolutePath().toString());
        return graphNode;
    }

    @Override
    Map<IRI, PropertyMap> getPropNames(GraphNode node, String depthHeader) {
        return WebDavUtils.getCollectionProps(null, null, null, node,
                            depthHeader, false /* doesNotIncludeValues */);
    }

    @Override
    Map<IRI, PropertyMap> getPropsByName(Node requestNode, GraphNode node,
            String depthHeader) {
        Map<IRI, PropertyMap> result;
        NodeList children = requestNode.getChildNodes();
        result = WebDavUtils.getPropsByName(children, node, depthHeader,
                true /* includeValues */);
        return result;
    }

    @Override
    Map<IRI, PropertyMap> getAllProps(GraphNode node, String depthHeader) {
        return WebDavUtils.getCollectionProps(null, null, null, node,
                            depthHeader, true /* includeValues */);
    }

    /*-----------------------*
     * Not Supported Methods * 
     *-----------------------*/
    
    /**
     * Locks a resource
     *
     * @return returns a 501 Not Implemented response
     */
    @LOCK
    public Object lock() {
        return Response.status(501/* Not Implemented */).build();
    }

    /**
     * Unlocks a resource
     *
     * @return returns a 501 Not Implemented response
     */
    @UNLOCK
    public Object unlock() {
        return Response.status(501/* Not Implemented */).build();
    }

    /**
     * Copies a resource
     *
     * @return returns a 501 Not Implemented response
     */
    @COPY
    public Object copy() {
        return Response.status(501/* Not Implemented */).build();
    }
}
