package org.apache.maven.doxia.site.decoration.inheritance;

/*
 * 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.
 */

import java.net.MalformedURLException;
import java.net.URL;

import org.codehaus.plexus.util.PathTool;

/**
 * Utilities that allow conversion of old and new pathes and URLs relative to each other.
 *
 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 * @author <a href="mailto:henning@apache.org">Henning P. Schmiedehausen</a>
 * @version $Id$
 */
public abstract class PathUtils
{
    /**
     * Private constructor.
     */
    private PathUtils()
    {
        // do not instantiate
    }

    /**
     * <p>convertPath.</p>
     *
     * @param oldPath not null
     * @param newPath not null
     * @return a PathDescriptor converted by the new path
     * @throws java.net.MalformedURLException if any
     */
    public static final PathDescriptor convertPath( final PathDescriptor oldPath, final PathDescriptor newPath )
        throws MalformedURLException
    {
        String relative = getRelativePath( oldPath, newPath );

        if ( relative == null )
        {
            return oldPath;
        }

        return new PathDescriptor( relative );
    }

    /**
     * <p>getRelativePath.</p>
     *
     * @param oldPathDescriptor not null
     * @param newPathDescriptor not null
     * @return a relative path depending if PathDescriptor is a file or a web url.
     * @see PathTool#getRelativeFilePath(String, String)
     * @see PathTool#getRelativeWebPath(String, String)
     */
    public static final String getRelativePath( final PathDescriptor oldPathDescriptor,
                                                final PathDescriptor newPathDescriptor )
    {
        // Cannot convert from URL to file.
        if ( oldPathDescriptor.isFile() )
        {
            if ( !newPathDescriptor.isFile() )
            {
                // We want to convert from a file to an URL. This is normally not possible...
                if ( oldPathDescriptor.isRelative() )
                {
                    // unless the old path is a relative path. Then we might convert an existing
                    // site into a new URL using resolvePaths()...
                    return oldPathDescriptor.getPath();
                }

                // The old path is not relative. Bail out.
                return null;
            }
        }

        // Don't optimize to else. This might also be old.isFile && new.isFile ...
        if ( !oldPathDescriptor.isFile() )
        {
            // URLs, determine if they share protocol and domain info
            URL oldUrl = oldPathDescriptor.getPathUrl();
            URL newUrl = newPathDescriptor.getPathUrl();

            if ( oldUrl == null || newUrl == null )
            {
                // One of the sites has a strange URL. no relative path possible, bail out.
                return null;
            }

            if ( ( newUrl.getProtocol().equalsIgnoreCase( oldUrl.getProtocol() ) )
                            && ( newUrl.getHost().equalsIgnoreCase( oldUrl.getHost() ) )
                            && ( newUrl.getPort() == oldUrl.getPort() ) )
            {
                // Both paths point to the same site. So we can use relative paths.

                String oldPath = oldPathDescriptor.getPath();
                String newPath = newPathDescriptor.getPath();

                return PathTool.getRelativeWebPath( newPath, oldPath );
            }

            // Different sites. No relative Path possible.
            return null;
        }

        // Both Descriptors point to a path. We can build a relative path.
        String oldPath = oldPathDescriptor.getPath();
        String newPath = newPathDescriptor.getPath();

        if ( oldPath == null || newPath == null )
        {
            // One of the sites has a strange URL. no relative path possible, bail out.
            return null;
        }

        return PathTool.getRelativeFilePath( oldPath, newPath );
    }
}
