// 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 com.cloud.bridge.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.SignatureException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Iterator;
import java.util.TreeMap;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;


public class EC2RestAuth {
    protected final static Logger logger = Logger.getLogger(RestAuth.class);

	// TreeMap: used to Sort the UTF-8 query string components by parameter name with natural byte ordering
	protected TreeMap<String, String> queryParts               = null;   // used to generate a CanonicalizedQueryString
	protected String                  canonicalizedQueryString = null;    
	protected String                  hostHeader               = null;    
	protected String                  httpRequestURI           = null;   
	
	public EC2RestAuth() {
		// these must be lexicographically sorted
		queryParts = new TreeMap<String, String>();
	}

	public static Calendar parseDateString( String created ) {
		DateFormat formatter = null;
        Calendar cal = Calendar.getInstance();
	    
	    // -> for some unknown reason SimpleDateFormat does not properly handle the 'Z' timezone
	    if (created.endsWith( "Z" )) created = created.replace( "Z", "+0000" );
	    	
		try {
	        formatter = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssz" );
	        cal.setTime( formatter.parse( created )); 
            return cal;
		} catch( Exception e ) {}
	
		try {
	        formatter = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssZ" );
	        cal.setTime( formatter.parse( created )); 
            return cal;
		} catch( Exception e ) {}

		
        // -> the time zone is GMT if not defined	
	    try {      
	        formatter = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss" );
	        cal.setTime( formatter.parse( created )); 
	        
	        created = created + "+0000";
	        formatter = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssZ" );
	        cal.setTime( formatter.parse( created )); 
            return cal;	        
		} catch( Exception e ) {}
		
		
		// -> including millseconds?
		try {
	        formatter = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.Sz" );
	        cal.setTime( formatter.parse( created )); 
            return cal;
		} catch( Exception e ) {}
		
		try {
	        formatter = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SZ" );
	        cal.setTime( formatter.parse( created )); 
            return cal;
		} catch( Exception e ) {}

		
		// -> the CloudStack API used to return this format for some calls
		try {
		    formatter = new SimpleDateFormat( "EEE MMM dd HH:mm:ss z yyyy" );
		    cal.setTime( formatter.parse( created )); 
            return cal;	              
		} catch( Exception e ) {}
		
		return null;
	}

	/**
	 * Assuming that a port number is to be included.
	 * 
	 * @param header - contents of the "Host:" header, skipping the 'Host:' preamble. 
	 */
	public void setHostHeader( String hostHeader ) {
		if ( null == hostHeader ) 
			 this.hostHeader = null;
	    else this.hostHeader = hostHeader.trim().toLowerCase();
	}
	
	public void setHTTPRequestURI( String uri ) {
		if ( null == uri || 0 == uri.length()) 
			 this.httpRequestURI = new String( "/" );
		else this.httpRequestURI = uri.trim();
	}

	/**
	 * The given query string needs to be pulled apart, sorted by paramter name, and reconstructed.
	 * We sort the query string values via a TreeMap.
	 * 
	 * @param query - this string still has all URL encoding in place.
	 */
	public void setQueryString( String query ) {
		String parameter = null;
		
		if (null == query) {
			this.canonicalizedQueryString = null;
			return;
		}
	
		// -> sort by paramter name
		String[] parts = query.split( "&" );
		if (null != parts) {
			for( int i=0; i < parts.length; i++ ) {
				
				parameter = parts[i];
				
				if (parameter.startsWith( "?" )) parameter = parameter.substring( 1 );
				
				// -> don't include a 'Signature=' parameter
				if (parameter.startsWith( "Signature=")) continue;
			
				int offset = parameter.indexOf( "=" );
				if ( -1 == offset )
					 queryParts.put( parameter, parameter + "=" );
				else queryParts.put( parameter.substring( 0, offset ), parameter );
			}
		}
		
		// -> reconstruct into a canonicalized format
		Collection<String> headers     = queryParts.values();
		Iterator<String>   itr         = headers.iterator();
		StringBuffer       reconstruct = new StringBuffer();
		int                count       = 0;
		
		while( itr.hasNext()) {
			if (0 < count) reconstruct.append( "&" );
			reconstruct.append( itr.next());
			count++;
		}
		canonicalizedQueryString = reconstruct.toString();	
	}

	
	/**
	 * The request is authenticated if we can regenerate the same signature given 
	 * on the request.  Before calling this function make sure to set the header values
	 * defined by the public values above.
	 * 
	 * @param httpVerb  - the type of HTTP request (e.g., GET, PUT)
	 * @param secretKey - value obtained from the AWSAccessKeyId
	 * @param signature - the signature we are trying to recreate, note can be URL-encoded
	 * @param method    - { "HmacSHA1", "HmacSHA256" }
	 * 
	 * @throws SignatureException 
	 * 
	 * @return true if request has been authenticated, false otherwise
	 * @throws UnsupportedEncodingException 
	 */
	public boolean verifySignature( String httpVerb, String secretKey, String signature, String method )
	    throws SignatureException, UnsupportedEncodingException {
		
		if (null == httpVerb || null == secretKey || null == signature) return false;
		
		httpVerb  = httpVerb.trim();
		secretKey = secretKey.trim();
		signature = signature.trim();
		
		// -> first calculate the StringToSign after the caller has initialized all the header values
		String StringToSign = genStringToSign( httpVerb );
		String calSig = calculateRFC2104HMAC( StringToSign, secretKey, method.equalsIgnoreCase( "HmacSHA1" ));
			
		// -> the passed in signature is defined to be URL encoded? (and it must be base64 encoded)
		int offset = signature.indexOf( "%" );
		if (-1 != offset) signature = URLDecoder.decode( signature, "UTF-8" );
	
        boolean match = signature.equals( calSig );
        if (!match) logger.error( "Signature mismatch, [" + signature + "] [" + calSig + "] over [" + StringToSign + "]" );
        return match;
	}

	
	/**
	 * This function generates the single string that will be used to sign with a users
	 * secret key.
	 * 
	 * StringToSign = HTTP-Verb + "\n" +
	 * ValueOfHostHeaderInLowercase + "\n" +
     * HTTPRequestURI + "\n" +  
	 * CanonicalizedQueryString
	 * 
	 * @return The single StringToSign or null.
     */
	private String genStringToSign( String httpVerb ) {
		StringBuffer stringToSign = new StringBuffer();
	
		stringToSign.append( httpVerb ).append( "\n" );
		
		if (null != this.hostHeader) stringToSign.append( this.hostHeader );
		stringToSign.append( "\n" );
		
		if (null != this.httpRequestURI) stringToSign.append( this.httpRequestURI );
		stringToSign.append( "\n" );

		if (null != this.canonicalizedQueryString) stringToSign.append( this.canonicalizedQueryString );
		
		if (0 == stringToSign.length())
			 return null;
		else return stringToSign.toString();
	}

		
    /**
     * Create a signature by the following method:
     *     new String( Base64( SHA1 or SHA256 ( key, byte array )))
     * 
     * @param signIt    - the data to generate a keyed HMAC over
     * @param secretKey - the user's unique key for the HMAC operation
     * @param useSHA1   - if false use SHA256
     * @return String   - the recalculated string
     * @throws SignatureException
     */
    private String calculateRFC2104HMAC( String signIt, String secretKey, boolean useSHA1 )
        throws SignatureException {
    	SecretKeySpec key = null;
    	Mac    hmacShaAlg = null;
    	String result     = null;
 	    
   	    try { 	
   	    	if ( useSHA1 ) {
   	    		 key = new SecretKeySpec( secretKey.getBytes(), "HmacSHA1" );
   	    		 hmacShaAlg = Mac.getInstance( "HmacSHA1" );
   	    	}
   	    	else {
   	    		 key = new SecretKeySpec( secretKey.getBytes(), "HmacSHA256" );
   	    		 hmacShaAlg = Mac.getInstance( "HmacSHA256" );
   	    	}
   	    	
   	    	hmacShaAlg.init( key ); 
   	    	byte [] rawHmac = hmacShaAlg.doFinal( signIt.getBytes());
            result = new String( Base64.encodeBase64( rawHmac ));
            
   	    } catch( Exception e ) {
   		    throw new SignatureException( "Failed to generate keyed HMAC on REST request: " + e.getMessage());
   	    }
   	    return result.trim();
    }
}
