/** 
 * 
 * Copyright 2004 Protique Ltd
 * 
 * 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.activemq.util;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * Some URI based helper methods.
 * 
 * @version $Revision: 1.1.1.1 $
 */
public class URIHelper {
    /**
     * Parsers the query string of the URI into a map of key-value pairs
     */
    public static Map parseQuery(URI uri) {
        return parseQuery(getLastQuery(uri));
    }

    /**
     * Parsers the query string of the URI into a map of key-value pairs
     */
    public static Map parseQuery(String query) {
        Map answer = new HashMap();
        if (query != null) {
            if (query.startsWith("?")) {
                query = query.substring(1);
            }
            StringTokenizer iter = new StringTokenizer(query, "&");
            while (iter.hasMoreTokens()) {
                String pair = iter.nextToken();
                addKeyValuePair(answer, pair);
            }
        }
        return answer;
    }

    /**
     * Get the query str
     * @param uri
     * @return the last query - the URI could be a composite
     */
    public static String getLastQuery(URI uri) {
        String result = null;
        if (uri != null) {
            String uriString = uri.toString();
            if (uriString != null) {
                int index = uri.toString().lastIndexOf('?');
                if (index >= 0 && (index + 1) < uriString.length()) {
                    result = uriString.substring(index + 1);
                }
            }
        }
        return result;
    }
    
    /**
     * Get the Path
     * @param uri
     * @return the last path - the URI could be a composite
     */
    public static String getLastPath(URI uri) {
        
        String path = uri.getPath();
        if(path==null) {
            path = uri.getRawSchemeSpecificPart();
        }
        
        // Skip to the last composite uri in the path.
        URIHelper helper = new URIHelper(path);
        while( helper.hasNext() ) {
            path = helper.getNext();
        }

        // Was the last thing in the composite a URI?
        if( path.indexOf(":") >=0 ) {
	        try {
	            path = new URI(path).getPath();
	        } catch (URISyntaxException e) {
	        }
        }
        
        path = removeInitialSlash(path).trim();
        if( path.length() == 0 )
            return null;
        
        return path;
    }

    /**
     * @param path
     * @return
     */
    private static String removeInitialSlash(String path) {
        if( path.length()>0 && path.charAt(0)=='/' ) {
            return path.substring(1);
        }
        return path;
    }

    protected static void addKeyValuePair(Map answer, String pair) {
        int idx = pair.indexOf('=');
        String name = null;
        String value = null;
        if (idx >= 0) {
            name = pair.substring(0, idx);
            if (++idx < pair.length()) {
                value = pair.substring(idx);
            }
        }
        else {
            name = pair;
        }
        answer.put(name, value);
    }
    private StringTokenizer tokenizer;

    /**
     * Create URIHelper with a path
     * 
     * @param path
     */
    public URIHelper(String path) {
        if (path != null) {
            this.tokenizer = new StringTokenizer(strip(path), ",");
        }
    }

    public boolean hasNext() {
        return tokenizer == null ? false : tokenizer.hasMoreTokens();
    }

    public String getNext() {
        return tokenizer == null ? null : tokenizer.nextToken();
    }

    private String strip(String str) {
        String result = null;
        if (str != null) {
            result = str.trim();
            int index = result.indexOf('(');
            if (index >= 0 && (index + 1) < result.length()) {
                result = result.substring(index + 1);
                index = result.lastIndexOf(')');
                result = result.substring(0, index);
            }
        }
        return result;
    }
}