/*
 * Created on Jul 13, 2009
 * Created by Paul Gardner
 * 
 * Copyright 2009 Vuze, Inc.  All rights reserved.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License only.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */


package com.aelitis.azureus.core.devices.impl;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.gudy.azureus2.core3.config.COConfigurationManager;

import org.gudy.azureus2.core3.torrent.TOTorrent;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.TimeFormatter;
import org.gudy.azureus2.core3.util.UrlUtils;
import org.gudy.azureus2.core3.xml.util.XUXmlWriter;

import org.gudy.azureus2.plugins.torrent.Torrent;
import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageRequest;
import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageResponse;

import com.aelitis.azureus.core.devices.Device;
import com.aelitis.azureus.core.rssgen.RSSGeneratorPlugin;
import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;

public class 
DeviceManagerRSSFeed 
	implements RSSGeneratorPlugin.Provider
{
	private static final String PROVIDER = "devices";
	
	private DeviceManagerImpl		manager;
		
	private RSSGeneratorPlugin		generator;
	
	protected
	DeviceManagerRSSFeed(
		DeviceManagerImpl	_manager )
	{
		manager 	= _manager;
		generator	= RSSGeneratorPlugin.getSingleton();
		
		generator.registerProvider( PROVIDER, this );
	}
		
	public boolean
	isEnabled()
	{
		return( manager.isRSSPublishEnabled());
	}
	
	public String
	getFeedURL()
	{
		return( generator.getURL() + PROVIDER );
	}
	
	public boolean
	generate(
		TrackerWebPageRequest		request,
		TrackerWebPageResponse		response )
	
		throws IOException
	{
		InetSocketAddress	local_address = request.getLocalAddress();
		
		if ( local_address == null ){
			
			return( false );
		}
		
		URL	url	= request.getAbsoluteURL();
					
		String path = url.getPath();
		
		path = path.substring( PROVIDER.length()+1);
		
		DeviceImpl[] devices = manager.getDevices();
		
		OutputStream os = response.getOutputStream();

		PrintWriter pw = new PrintWriter(new OutputStreamWriter( os, "UTF-8" ));

		if ( path.length() <= 1 ){
			
			response.setContentType( "text/html; charset=UTF-8" );
			
			pw.println( "<HTML><HEAD><TITLE>Vuze Device Feeds</TITLE></HEAD><BODY>" );
			
			for ( DeviceImpl d: devices ){
			
				if ( d.getType() != Device.DT_MEDIA_RENDERER || d.isHidden() || !d.isRSSPublishEnabled()){
					
					continue;
				}

				String	name = d.getName();
								
				pw.println( "<LI><A href=\"" + PROVIDER + "/" + URLEncoder.encode( name, "UTF-8" ) + "\">" + name + "</A></LI>" );
			}
			
			pw.println( "</BODY></HTML>" );
			
		}else{
			
			String	device_name = URLDecoder.decode( path.substring( 1 ), "UTF-8" );
			
			DeviceImpl	device = null;
			
			for ( DeviceImpl d: devices ){
				
				if ( d.getName().equals( device_name ) && d.isRSSPublishEnabled()){
					
					device = d;
					
					break;
				}
			}
			
			if ( device == null ){
				
				response.setReplyStatus( 404 );
				
				return( true );
			}
			
			URL	feed_url = url;

				// absolute url is borked as it doesn't set the host properly. hack 
			
			String	host = (String)request.getHeaders().get( "host" );
			
			if ( host != null ){
				
				int	pos = host.indexOf( ':' );
				
				if ( pos != -1 ){
					
					host = host.substring( 0, pos );
				}
				
				feed_url = UrlUtils.setHost( url, host );
			}
			
			if ( device instanceof DeviceMediaRendererImpl ){
				
				((DeviceMediaRendererImpl)device).browseReceived();
			}
			
			response.setContentType( "application/xml" );
			
			pw.println( "<?xml version=\"1.0\" encoding=\"utf-8\"?>" );
			
			pw.println( 
					"<rss version=\"2.0\" " + 
					"xmlns:vuze=\"http://www.vuze.com\" " +
					"xmlns:media=\"http://search.yahoo.com/mrss/\" " +
					"xmlns:atom=\"http://www.w3.org/2005/Atom\" " +
					"xmlns:itunes=\"http://www.itunes.com/dtds/podcast-1.0.dtd\">" );
			
			pw.println( "<channel>" );
			
			String channel_title = "Vuze Device: " + escape( device.getName());
					
			pw.println( "<title>" + channel_title + "</title>" );
			pw.println( "<link>http://vuze.com</link>" );
			pw.println( "<atom:link href=\"" + feed_url.toExternalForm() + "\" rel=\"self\" type=\"application/rss+xml\" />" );
			
			pw.println( "<description>Vuze RSS Feed for device " + escape( device.getName()) + "</description>" );
			
			pw.println("<itunes:image href=\"http://www.vuze.com/img/vuze_icon_128.png\"/>");
			pw.println("<image><url>http://www.vuze.com/img/vuze_icon_128.png</url><title>" + channel_title + "</title><link>http://vuze.com</link></image>");
			
					
			TranscodeFileImpl[] _files = device.getFiles();
			
			List<TranscodeFileImpl>	files = new ArrayList<TranscodeFileImpl>( _files.length );
			
			files.addAll( Arrays.asList( _files ));
			
			Collections.sort(
				files,
				new Comparator<TranscodeFileImpl>()
				{
					public int  
					compare(
						TranscodeFileImpl f1, 
						TranscodeFileImpl f2) 
					{
						long	added1 = f1.getCreationDateMillis()/1000;
						long	added2 = f2.getCreationDateMillis()/1000;

						return((int)(added2 - added1 ));
					}
				});
										
			String	feed_date_key = "devices.feed_date." + device.getID();
			
			long feed_date = COConfigurationManager.getLongParameter( feed_date_key );

			boolean new_date = false;
			
			for ( TranscodeFileImpl file: files ){
				
				long	file_date = file.getCreationDateMillis();
				
				if ( file_date > feed_date ){
					
					new_date = true;
					
					feed_date = file_date;
				}
			}
			
			if ( new_date ){
				
				COConfigurationManager.setParameter( feed_date_key, feed_date );
			}
			
			pw.println(	"<pubDate>" + TimeFormatter.getHTTPDate( feed_date ) + "</pubDate>" );

			for ( TranscodeFileImpl file: files ){
										
	  			if ( !file.isComplete()){
	  					
	  				if ( !file.isTemplate()){
	  						
	  					continue;
	  				}
	  			}
	  		
				try{
	  				pw.println( "<item>" );
	  				
	  				pw.println( "<title>" + escape( file.getName()) + "</title>" );
	  								
	  				pw.println(	"<pubDate>" + TimeFormatter.getHTTPDate( file.getCreationDateMillis()) + "</pubDate>" );
	  				
	  				pw.println( "<guid isPermaLink=\"false\">" + escape( file.getKey()) + "</guid>" );
	  				
	  				String[] categories = file.getCategories();
	  				
	  				for ( String category: categories ){
	  					
	  					pw.println( "<category>" + category + "</category>" );
	  				}
	  				
	  				String mediaContent = "";
	  				
	  				URL stream_url = file.getStreamURL( feed_url.getHost() );
	  				
	  				if ( stream_url != null ){
	  					
	  					String url_ext = stream_url.toExternalForm();
	  					
	  					long fileSize = file.getTargetFile().getLength();
	  					
	  					pw.println( "<link>" + url_ext + "</link>" );
	  					
	  					mediaContent = "<media:content medium=\"video\" fileSize=\"" +
											fileSize + "\" url=\"" + url_ext + "\""; 
	  					
	  					String	mime_type = file.getMimeType();
	  					
	  					if ( mime_type != null ){
	  						
	  						mediaContent += " type=\"" + mime_type + "\"";
	  					}
	  				
						pw.println("<enclosure url=\"" + url_ext
								+ "\" length=\"" + fileSize
								+ (mime_type == null ? "" : "\" type=\"" + mime_type)
								+ "\"></enclosure>");		
	  				}
	  				
	   				String	thumb_url		= null;
	  				String	author			= null;
	  				String	description		= null;
	  				
	  				try{
	  					Torrent torrent = file.getSourceFile().getDownload().getTorrent();
	  				
	  					TOTorrent toTorrent = PluginCoreUtils.unwrap(torrent);
					
	  					long duration_secs = PlatformTorrentUtils.getContentVideoRunningTime(toTorrent);
	  					
	  					if ( mediaContent.length() > 0 && duration_secs > 0 ){
	  						
	  						mediaContent += " duration=\"" + duration_secs + "\"";
	  					}
	  					  					
	  					thumb_url = PlatformTorrentUtils.getContentThumbnailUrl(toTorrent);
	  					
	  					author = PlatformTorrentUtils.getContentAuthor(toTorrent);
	  								
	  					description= PlatformTorrentUtils.getContentDescription(toTorrent);
	  					
	  					if ( description != null ){
	  						
	  						description = escapeMultiline( description );

	  						/*
	  						if ( thumb_url != null ){
	  							
	  		
	  							pw.println( "<description type=\"text/html\">" + 
	  								escape( "<div style=\"text-align: justify;padding: 5px;\"><img style=\"float: left;margin-right: 15px;margin-bottom: 15px;\" src=\"" + thumb_url + "\"/>" ) +
	  								description + 
	  								escape( "</div>" ) +
	  								"</description>" );
	  						}else{
	  						*/	
	  							pw.println( "<description>" + description + "</description>");
	  						//}
	   					}					
	  				}catch( Throwable e ){
	  				}
	
	  					// media elements
	  				
	  				if ( mediaContent.length() > 0 ){
	  					  						
	  					pw.println( mediaContent += "></media:content>" );
	  				}
	
	  				pw.println( "<media:title>" + escape( file.getName()) + "</media:title>" );
	
					if ( description != null ){
							
						pw.println( "<media:description>" + description + "</media:description>" );
					}
					
					if ( thumb_url != null ) {
							
						pw.println("<media:thumbnail url=\"" + thumb_url + "\"/>" );
					}
	 
	 					// iTunes elements
	 					
					if ( thumb_url != null ) {
							
						pw.println("<itunes:image href=\"" + thumb_url + "\"/>");
					}
	
	 				if ( author != null ){
	  					
	  					pw.println("<itunes:author>" + escape(author) + "</itunees:author>");
	  				}
	  				
	  				pw.println( "<itunes:summary>" + escape( file.getName()) + "</itunes:summary>" );
	  				pw.println( "<itunes:duration>" + TimeFormatter.formatColon( file.getDurationMillis()/1000 ) + "</itunes:duration>" );
	  				
	  				pw.println( "</item>" );
	  				
				}catch( Throwable e ){
					
					Debug.out(e);
				}
			}
		
			pw.println( "</channel>" );
			
			pw.println( "</rss>" );
		}
		
		pw.flush();
		
		return( true );
	}
	
	protected String
	escape(
		String	str )
	{
		return( XUXmlWriter.escapeXML(str));
	}

	protected String
	escapeMultiline(
		String	str )
	{
		return( XUXmlWriter.escapeXML(str.replaceAll("[\r\n]+", "<BR>")));
	}
}
