/*
 * Copyright (C) 2011 Citrix Systems, Inc.  All rights reserved.
 * 
 * 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 com.cloud.stack;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.SignatureException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

/**
 * CloudStackCommand wraps command properties that are being sent to CloudStack
 * 
 * @author Kelven Yang
 */
public class CloudStackCommand {
	Map<String, String> _params = new HashMap<String, String>(); 
	
	public CloudStackCommand(String cmdName) {
		this(cmdName, "json");
	}
	
	public CloudStackCommand(String cmdName, String responseType) {
		_params.put("command", cmdName);
		if(responseType != null)
			_params.put("response", responseType);
	}
	
	public CloudStackCommand setParam(String paramName, String paramValue) {
		assert(paramName != null);
		assert(paramValue != null);
	
		_params.put(paramName, paramValue);
		return this;
	}
	
	public String signCommand(String apiKey, String secretKey) throws SignatureException {
		assert(_params.get("command") != null);
		
		List<String> paramNames = new ArrayList<String>();
		for(String paramName : _params.keySet())
			paramNames.add(paramName);
		
		paramNames.add("apikey");
		Collections.sort(paramNames);

		StringBuffer sb = new StringBuffer();
		for(String name : paramNames) {
			String value;
			if("apikey".equals(name))
				value = apiKey;
			else
				value = _params.get(name);
			
			assert(value != null);
			
			value = urlSafe(value);
			
			if(sb.length() == 0) {
				sb.append(name).append("=").append(value);
			} else {
				sb.append("&").append(name).append("=").append(value);
			}
		}
		
		String signature = calculateRFC2104HMAC(sb.toString().toLowerCase(), secretKey);
		return composeQueryString(apiKey, signature);
	}
	
	private String composeQueryString(String apiKey, String signature) {
		StringBuffer sb = new StringBuffer();
		String name;
		String value;
		
		// treat command specially (although not really necessary )
		name = "command";
		value = _params.get(name);
		if(value != null) {
			value = urlSafe(value);
			sb.append(name).append("=").append(value);
		}
		
		for(Map.Entry<String, String> entry : _params.entrySet()) {
			name = entry.getKey();
			
			if(!"command".equals(name)) {
				value = urlSafe(entry.getValue());
				
				if(sb.length() == 0)
					sb.append(name).append("=").append(value);
				else
					sb.append("&").append(name).append("=").append(value);
			}
		}
		
		sb.append("&apikey=").append(urlSafe(apiKey));
		sb.append("&signature=").append(urlSafe(signature));
		
		return sb.toString();
	}
	
    private String calculateRFC2104HMAC( String signIt, String secretKey ) throws SignatureException {
   	    String result = null;
   	    try { 	 
   	    	SecretKeySpec key = new SecretKeySpec( secretKey.getBytes(), "HmacSHA1" );
   	        Mac hmacSha1 = Mac.getInstance( "HmacSHA1" );
   	        hmacSha1.init( key ); 
            byte [] rawHmac = hmacSha1.doFinal( signIt.getBytes());
            result = new String( Base64.encodeBase64( rawHmac ));
   	    } catch( Exception e ) {
   		    throw new SignatureException( "Failed to generate keyed HMAC on soap request: " + e.getMessage());
   	    }
   	    return result.trim();
    }
   
    private String urlSafe(String value) {
    	try {
    		if (value != null)
    			return URLEncoder.encode(value, "UTF-8").replaceAll("\\+", "%20");
    		else 
    			return null;
		} catch (UnsupportedEncodingException e) {
			assert(false);
		}
		
		return value;
    }
}
