// Video SEO Developer Kit Version 1.4
// Feb 10, 2010, Ooyala
//
// The Video SEO Develop Kit is a set of methods which enable publishers to increase the visibility of their content
// to search engines. The Develop Kit contains a primary class OoyalaSEOFriendlyVideo, and two primary methods: 
// header() and body().
//
// See example.jsp for an example of how to call these methods

package ooyala;

import java.util.*;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;



public class OoyalaSEOFriendlyVideo{
	// Creates an SEOFriendlyVideo instance. Performs a calls to Ooyala's API to obtain relevant SEO data.
    //
    // partner_code: the partner code found in your Backlot > Account > Developers tab
    // secret_code: the secret code found in your Backlot > Account > Developers tab
    // embed_code: the embed code of your video or channel, found in your Manage > Embed tab

	static String partner_code;
	static String secret_code;
	static String embed_code;
	static int cache_for_num_seconds;
	static String title;
	static String description;
	static String metadata;
	static String labels_html;
	
	public OoyalaSEOFriendlyVideo(String partnerCode, String secretCode, String embedCode) {
		partner_code = partnerCode;
		secret_code = secretCode;
		embed_code = embedCode;
		cache_for_num_seconds = 900;

		fetch_data();
	}

	private static String query(HashMap<String,String> params) {
		return send_request("query", params);
	}
	
	private static String send_request(String request_type, HashMap<String,String> params) {

		// Round expires to nearest @cache_for_num_seconds interval
    	float t_float = (float) (System.currentTimeMillis()/1000 + 15) / cache_for_num_seconds;
    	int expires = (int) Math.ceil( t_float ) * cache_for_num_seconds;
    	
	    params.put("expires", String.valueOf(expires));
    	
	    String string_to_sign = secret_code;
	    String url = "http://cdn.api.ooyala.com/partner/"+request_type+"?pcode="+partner_code;
		
	    SortedSet<String> sortedset= new TreeSet<String>(params.keySet());
	    Iterator<String> keyIt = sortedset.iterator();
	    
	    while(keyIt.hasNext()){
	    	String key = (String)keyIt.next();
	    	string_to_sign += key+"="+params.get(key).toString();
	    	try {
	    		url += "&"+URLEncoder.encode(key, "UTF-8") +"="+URLEncoder.encode(params.get(key).toString(), "UTF-8");		
	    	} catch (UnsupportedEncodingException e) {
	    		e.printStackTrace();
	    	} 
	    }
    
		// Create a Message Digest from a Factory method
	    MessageDigest md = getDigest("SHA-256");
		// Create the digest from the message
		byte[] digest = md.digest(string_to_sign.getBytes());
		
		String signature = Base64.encode(digest).trim().replace("=", "");
    	try {
    		url += "&signature="+URLEncoder.encode(signature, "UTF-8");
    	} catch (UnsupportedEncodingException e) {
    		e.printStackTrace();
    	} 
    	
    	return url;
		
	}
	
    private static MessageDigest getDigest(String algorithm) {
        try {
            return MessageDigest.getInstance(algorithm);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e.getMessage());
        }
    }
    
    // Returns a string to be inserted into the header of your page.
    public static String header() {
       	
		return "\n"+
"	<title>"+title+"</title>\n"+
"	<meta name=\"description\" content=\""+description+"\" />\n"+
"	<meta name=\"keywords\" content=\""+metadata+"\" />\n"+
"";
	}
    
	// Returns a string to be inserted into the body of your page.
	//
	// width: the width of your video embed
	// height: the height of your video embed
    public static String body(int width, int height) {
    	
    	
    	// setting the player ID, this can be changed with any other value
		String player_id = "flashVideoPlayer";
		
		// use a fixed size div to embed the SEO text. We add overflow: hidden to make sure it doesn't get a larger than the size of the player
		return "\n"+
"	<div id=\"videoPlayer\" style=\"width: "+width+"px; height: "+height+"px; overflow: hidden; text-overflow: hidden\">\n"+
"	  <script src=\"http://player.ooyala.com/player.js?width="+width+"&height="+height+"&embedCode="+embed_code+"\"></script>\n"+
"	  <noscript>\n"+
"		<object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" id=\""+player_id+"\" width=\""+width+"\" height=\""+height+"\"\n"+
"				codebase=\"http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab\">\n"+
"		  <param name=\"movie\" value=\"http://player.ooyala.com/player.swf?embedCode="+embed_code+"\" />\n"+
"		  <param name=\"bgcolor\" value=\"#000000\" />\n"+
"		  <param name=\"allowScriptAccess\" value=\"always\" />\n"+
"		  <param name=\"allowFullScreen\" value=\"true\" />\n"+
"		  <param name=\"flashvars\" value=\"embedType=directObjectTag&embedCode="+embed_code+"\"/>\n"+
"		  <embed src=\"http://player.ooyala.com/player.swf?embedCode="+embed_code+"\" bgcolor=\"#000000\" width=\""+width+"\" height=\""+height+"\"\n"+
"				 name=\""+player_id+"\" align=\"middle\" play=\"true\" loop=\"false\"\n"+
"				 allowscriptaccess=\"always\" allowfullscreen=\"true\" type=\"application/x-shockwave-flash\"\n"+
"				 flashvars=\"&embedCode="+embed_code+"\" pluginspage =\" http://www.adobe.com/go/getflashplayer\">\n"+
"		  </embed>\n"+
"		</object>\n"+
"	  </noscript>\n"+
"	  <h1>"+title+"</h1>\n"+
"	  <h2>"+description+"</h2>\n"+
"	  <h3>"+metadata+"</h3>\n"+
"	  "+labels_html+"\n"+
"	</div>\n"+
"";
    }
    
    
  	// Fetches title, description, labels and metadata from the Backlot API.
    private static void fetch_data() {
    	
    	// a query to the backlot console is made
    	HashMap<String,String> params = new HashMap<String, String>();
    	params.put("embedCode", embed_code);
    	params.put("fields", "labels, metadata");
	    String url = query(params);

	    Document doc = null;
    	try{
        	URL urlR = new URL(url);
	        URLConnection conn = urlR.openConnection();
	        // extract information
	        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	        DocumentBuilder builder = factory.newDocumentBuilder();
	        doc = builder.parse(conn.getInputStream());
    	}catch (Throwable e){
	        e.printStackTrace();
    	}

       	title = doc.getElementsByTagName("title").item(0).getFirstChild().getNodeValue();
    	description = doc.getElementsByTagName("description").item(0).getFirstChild().getNodeValue();

    	NodeList labelsNode = doc.getElementsByTagName("labels");
	    Element labelLine = (Element) labelsNode.item(0);
	    NodeList labels = labelLine.getElementsByTagName("label");
    	labels_html = "<ul>";
    	 for(int j=0; j < labels.getLength();j++){
             Element label = (Element) labels.item(j);
             labels_html += "<li>"+label.getFirstChild().getNodeValue().replaceFirst("/", "")+"</li>";
         }
    	labels_html += "</ul>";
    	
    	
		NodeList metadataNode = doc.getElementsByTagName("metadata");
	    Element line = (Element) metadataNode.item(0);
	    NodeList metadataItems = line.getElementsByTagName("metadataItem");
	    metadata = "";
        for(int i=0; i < metadataItems.getLength();i++){
            
            Element metadataItem = (Element) metadataItems.item(i);
            metadata += metadataItem.getAttribute("value") + ", ";
        }
        //removing the last comma from the metadata string 
        if (metadata.length() > 0){
        	metadata = metadata.substring(0, metadata.length()- 2);
        }
  
    }
    
}

