// 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.sample;

import java.io.FileInputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;

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

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;


/**
 *
 *
 *
 *
 *
 * 
 * 
 * 
 * 
 */

/**
 * Sample CloudStack Management User API Executor.
 * 
 * Prerequisites: - Edit usercloud.properties to include your host, apiUrl, apiKey, and secretKey - Use ./executeUserAPI.sh to
 * execute this test class
 * 
 * 
 */
public class UserCloudAPIExecutor {
    public static void main(String[] args) {
        // Host
        String host = null;

        // Fully qualified URL with http(s)://host:port
        String apiUrl = null;

        // ApiKey and secretKey as given by your CloudStack vendor
        String apiKey = null;
        String secretKey = null;

        try {
            Properties prop = new Properties();
            prop.load(new FileInputStream("usercloud.properties"));

            // host
            host = prop.getProperty("host");
            if (host == null) {
                System.out.println("Please specify a valid host in the format of http(s)://:/client/api in your usercloud.properties file.");
            }

            // apiUrl
            apiUrl = prop.getProperty("apiUrl");
            if (apiUrl == null) {
                System.out.println("Please specify a valid API URL in the format of command=&param1=&param2=... in your usercloud.properties file.");
            }

            // apiKey
            apiKey = prop.getProperty("apiKey");
            if (apiKey == null) {
                System.out.println("Please specify your API Key as provided by your CloudStack vendor in your usercloud.properties file.");
            }

            // secretKey
            secretKey = prop.getProperty("secretKey");
            if (secretKey == null) {
                System.out.println("Please specify your secret Key as provided by your CloudStack vendor in your usercloud.properties file.");
            }

            if (apiUrl == null || apiKey == null || secretKey == null) {
                return;
            }

            System.out.println("Constructing API call to host = '" + host + "' with API command = '" + apiUrl + "' using apiKey = '" + apiKey + "' and secretKey = '" + secretKey + "'");

            // Step 1: Make sure your APIKey is URL encoded
            String encodedApiKey = URLEncoder.encode(apiKey, "UTF-8");

            // Step 2: URL encode each parameter value, then sort the parameters and apiKey in
            // alphabetical order, and then toLowerCase all the parameters, parameter values and apiKey.
            // Please note that if any parameters with a '&' as a value will cause this test client to fail since we are using
            // '&' to delimit
            // the string
            List<String> sortedParams = new ArrayList<String>();
            sortedParams.add("apikey=" + encodedApiKey.toLowerCase());
            StringTokenizer st = new StringTokenizer(apiUrl, "&");
            String url = null;
            boolean first = true;
            while (st.hasMoreTokens()) {
                String paramValue = st.nextToken();
                String param = paramValue.substring(0, paramValue.indexOf("="));
                String value = URLEncoder.encode(paramValue.substring(paramValue.indexOf("=") + 1, paramValue.length()), "UTF-8");
                if (first) {
                    url = param + "=" + value;
                    first = false;
                } else {
                    url = url + "&" + param + "=" + value;
                }
                sortedParams.add(param.toLowerCase() + "=" + value.toLowerCase());
            }
            Collections.sort(sortedParams);

            System.out.println("Sorted Parameters: " + sortedParams);

            // Step 3: Construct the sorted URL and sign and URL encode the sorted URL with your secret key
            String sortedUrl = null;
            first = true;
            for (String param : sortedParams) {
                if (first) {
                    sortedUrl = param;
                    first = false;
                } else {
                    sortedUrl = sortedUrl + "&" + param;
                }
            }
            System.out.println("sorted URL : " + sortedUrl);
            String encodedSignature = signRequest(sortedUrl, secretKey);

            // Step 4: Construct the final URL we want to send to the CloudStack Management Server
            // Final result should look like:
            // http(s)://://client/api?&apiKey=&signature=
            String finalUrl = host + "?" + url + "&apiKey=" + apiKey + "&signature=" + encodedSignature;
            System.out.println("final URL : " + finalUrl);

            // Step 5: Perform a HTTP GET on this URL to execute the command
            HttpClient client = new HttpClient();
            HttpMethod method = new GetMethod(finalUrl);
            int responseCode = client.executeMethod(method);
            if (responseCode == 200) {
                // SUCCESS!
                System.out.println("Successfully executed command");
            } else {
                // FAILED!
                System.out.println("Unable to execute command with response code: " + responseCode);
            }

        } catch (Throwable t) {
            System.out.println(t);
        }
    }

    /**
     * 1. Signs a string with a secret key using SHA-1 2. Base64 encode the result 3. URL encode the final result
     * 
     * @param request
     * @param key
     * @return
     */
    public static String signRequest(String request, String key) {
        try {
            Mac mac = Mac.getInstance("HmacSHA1");
            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacSHA1");
            mac.init(keySpec);
            mac.update(request.getBytes());
            byte[] encryptedBytes = mac.doFinal();
            return URLEncoder.encode(Base64.encodeBase64String(encryptedBytes), "UTF-8");
        } catch (Exception ex) {
            System.out.println(ex);
        }
        return null;
    }
}
