//  Copyright 2004 The Apache Software Foundation
//
// 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.tapestry.engine;

import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
import org.apache.tapestry.*;
import org.apache.tapestry.resource.ClasspathResourceLocation;
import org.apache.tapestry.spec.IComponentSpecification;
import org.apache.tapestry.spec.ILibrarySpecification;

import java.util.*;

/**
 *  Implementation of {@link org.apache.tapestry.INamespace}
 *  that works with a {@link ISpecificationSource} to
 *  obtain page and component specifications as needed.
 *
 *  @author Howard Lewis Ship
 *  @version $Id$
 *  @since 2.2
 *
 **/

public class Namespace implements INamespace
{
    private ILibrarySpecification _specification;
    private ISpecificationSource _specificationSource;
    private String _id;
    private String _extendedId;
    private INamespace _parent;
    private boolean _frameworkNamespace;
    private boolean _applicationNamespace;

    /**
     *  Map of {@link org.apache.tapestry.spec.ComponentSpecification} keyed on page name.
     *  The map is synchronized because different threads may
     *  try to update it simultaneously (due to dynamic page
     *  discovery in the application namespace).
     * 
     **/

    private Map _pages = new ConcurrentHashMap();

    /**
     *  Map of {@link org.apache.tapestry.spec.ComponentSpecification} keyed on
     *  component alias.
     * 
     **/

    private Map _components = new ConcurrentHashMap();

    /**
     *  Map, keyed on id, of {@link INamespace}.
     * 
     **/

    private Map _children = new ConcurrentHashMap();

    public Namespace(
        String id,
        INamespace parent,
        ILibrarySpecification specification,
        ISpecificationSource specificationSource)
    {
        _id = id;
        _parent = parent;
        _specification = specification;
        _specificationSource = specificationSource;

        _applicationNamespace = (_id == null);
        _frameworkNamespace = FRAMEWORK_NAMESPACE.equals(_id);
    }

    public String toString()
    {
        StringBuffer buffer = new StringBuffer("Namespace@");
        buffer.append(Integer.toHexString(hashCode()));
        buffer.append('[');

        if (_applicationNamespace)
            buffer.append("<application>");
        else
            buffer.append(getExtendedId());

        buffer.append(']');

        return buffer.toString();
    }

    public String getId()
    {
        return _id;
    }

    public String getExtendedId()
    {
        if (_applicationNamespace)
            return null;

        if (_extendedId == null)
            _extendedId = buildExtendedId();

        return _extendedId;
    }

    public INamespace getParentNamespace()
    {
        return _parent;
    }

    public INamespace getChildNamespace(String id)
    {
        String firstId = id;
        String nextIds = null;

        // Split the id into first and next if it is a dot separated sequence
        int index = id.indexOf('.');
        if (index >= 0)
        {
            firstId = id.substring(0, index);
            nextIds = id.substring(index + 1);
        }

        // Get the first namespace
        INamespace result = (INamespace) _children.get(firstId);

        if (result == null)
        {
            result = createNamespace(firstId);

            _children.put(firstId, result);
        }

        // If the id is a dot separated sequence, recurse to find 
        // the needed namespace
        if (result != null && nextIds != null)
            result = result.getChildNamespace(nextIds);

        return result;
    }

    public List getChildIds()
    {
        return _specification.getLibraryIds();
    }

    public IComponentSpecification getPageSpecification(String name)
    {
        IComponentSpecification result = (IComponentSpecification) _pages.get(name);

        if (result == null)
        {
            result = locatePageSpecification(name);

            _pages.put(name, result);
        }

        return result;
    }

    public List getPageNames()
    {
        Set names = new HashSet();

        names.addAll(_pages.keySet());
        names.addAll(_specification.getPageNames());

        List result = new ArrayList(names);

        Collections.sort(result);

        return result;
    }

    public IComponentSpecification getComponentSpecification(String alias)
    {
        IComponentSpecification result = (IComponentSpecification) _components.get(alias);

        if (result == null)
        {
            result = locateComponentSpecification(alias);
            _components.put(alias, result);
        }

        return result;
    }

    public String getServiceClassName(String name)
    {
        return _specification.getServiceClassName(name);
    }

    public List getServiceNames()
    {
        return _specification.getServiceNames();
    }

    public ILibrarySpecification getSpecification()
    {
        return _specification;
    }

    private String buildExtendedId()
    {
        if (_parent == null)
            return _id;

        String parentId = _parent.getExtendedId();

        // If immediate child of application namespace

        if (parentId == null)
            return _id;

        return parentId + "." + _id;
    }

    /**
     *  Returns a string identifying the namespace, for use in
     *  error messages.  I.e., "Application namespace" or "namespace 'foo'".
     * 
     **/

    public String getNamespaceId()
    {
        if (_frameworkNamespace)
            return Tapestry.getMessage("Namespace.framework-namespace");

        if (_applicationNamespace)
            return Tapestry.getMessage("Namespace.application-namespace");

        return Tapestry.format("Namespace.nested-namespace", getExtendedId());
    }

    /**
     *  Gets the specification from the specification source.
     * 
     *  @throws ApplicationRuntimeException if the named page is not defined.
     * 
     **/

    private IComponentSpecification locatePageSpecification(String name)
    {
        String path = _specification.getPageSpecificationPath(name);

        if (path == null)
            throw new ApplicationRuntimeException(
                Tapestry.format("Namespace.no-such-page", name, getNamespaceId()));

        IResourceLocation location = getSpecificationLocation().getRelativeLocation(path);

        return _specificationSource.getPageSpecification(location);
    }

    private IComponentSpecification locateComponentSpecification(String type)
    {
        String path = _specification.getComponentSpecificationPath(type);

        if (path == null)
            throw new ApplicationRuntimeException(
                Tapestry.format("Namespace.no-such-alias", type, getNamespaceId()));

        IResourceLocation location = getSpecificationLocation().getRelativeLocation(path);

        return _specificationSource.getComponentSpecification(location);
    }

    private INamespace createNamespace(String id)
    {
        String path = _specification.getLibrarySpecificationPath(id);

        if (path == null)
            throw new ApplicationRuntimeException(
                Tapestry.format("Namespace.library-id-not-found", id, getNamespaceId()));

        IResourceLocation location = getSpecificationLocation().getRelativeLocation(path);

        // Ok, an absolute path to a library for an application whose specification
        // is in the context root is problematic, cause getRelativeLocation()
        // will still be looking in the context.  Handle this case with the
        // following little kludge:

        if (location.getResourceURL() == null && path.startsWith("/"))
            location = new ClasspathResourceLocation(_specification.getResourceResolver(), path);

        ILibrarySpecification ls = _specificationSource.getLibrarySpecification(location);

        return new Namespace(id, this, ls, _specificationSource);
    }

    public boolean containsPage(String name)
    {
        return _pages.containsKey(name) || (_specification.getPageSpecificationPath(name) != null);
    }

    /** @since 2.3 **/

    public String constructQualifiedName(String pageName)
    {
        String prefix = getExtendedId();

        if (prefix == null)
            return pageName;

        return prefix + SEPARATOR + pageName;
    }

    /** @since 3.0 **/

    public IResourceLocation getSpecificationLocation()
    {
        return _specification.getSpecificationLocation();
    }

    /** @since 3.0 **/

    public boolean isApplicationNamespace()
    {
        return _applicationNamespace;
    }

    /** @since 3.0 **/

    public synchronized void installPageSpecification(
        String pageName,
        IComponentSpecification specification)
    {
        _pages.put(pageName, specification);
    }

    /** @since 3.0 **/

    public synchronized void installComponentSpecification(
        String type,
        IComponentSpecification specification)
    {
        _components.put(type, specification);
    }

    /** @since 3.0 **/

    public boolean containsComponentType(String type)
    {
        return _components.containsKey(type)
            || (_specification.getComponentSpecificationPath(type) != null);
    }

    /** @since 3.0 **/

    public List getComponentTypes()
    {
        Set types = new HashSet();

        types.addAll(_components.keySet());
        types.addAll(_specification.getComponentTypes());

        List result = new ArrayList(types);

        Collections.sort(result);

        return result;
    }

    /** @since 3.0 **/

    public ILocation getLocation()
    {
        if (_specification == null)
            return null;

        return _specification.getLocation();
    }

}
