/**************************************************************
 *
 * 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.
 *
 *************************************************************/

import java.io.*;
import java.util.Vector;


public class SubscribedNewsgroups {


	private static NewsGroup[] allSubscribed = null;
	private static boolean windows = false;

	public static void main( String[] args ) {
		// Test the class
		SubscribedNewsgroups subscribed = new SubscribedNewsgroups();

		NewsGroup allGroups[] = subscribed.getNewsGroups();

		if( allGroups == null )
		{
			System.out.println("Could not find subscribed newsgroups from mozilla/netscape mailrc files");
		}
		else
		{
			for( int i=0; i < allGroups.length; i++ )
			{
				System.out.println( "Hostname is: " + allGroups[i].getHostName() + " Newsgroup is: " + allGroups[i].getNewsgroupName() );
			}
		}
	}



	// Only public method of the class
	// Returns and array of unique NewsGroup objects
	public NewsGroup[] getNewsGroups()
	{
		windows = false;
		if( System.getProperty( "os.name" ).indexOf( "Windows" ) != -1 )
		{
			windows = true;
		}

		String mozillaHome = "";
		if( windows )
		{
			mozillaHome = System.getProperty( "user.home" ) + System.getProperty( "file.separator" ) + "Application Data" + System.getProperty( "file.separator" ) + "Mozilla" + System.getProperty( "file.separator" ) + "Profiles";
			//System.out.println( "Windows mozilla path: " + mozillaHome );
		}
		else
		{
			mozillaHome = System.getProperty( "user.home" ) + System.getProperty( "file.separator" ) + ".mozilla";
			//System.out.println( "Unix/Linux mozilla path: " + mozillaHome );
		}
		if( !new File( mozillaHome ).isDirectory() )
		{
			//System.out.println("Could not find .mozilla directory");
			return null;
		}
		//System.out.println(".mozilla directory found");

		// Get all the profiles belonging to the user
		File profiles[] = findProfiles( new File ( mozillaHome ) );
		if( profiles.length < 1 )
		{
			//System.out.println("Could not find Profiles");
			return null;
		}
		//System.out.println("Profiles found");

		// Get the News directory for each profile
		File allNewsDirs[] = new File[ profiles.length ];
		for( int i=0; i < profiles.length; i++ ) {
			File newsDir = findNewsDir( profiles[i] );
			allNewsDirs[i] = newsDir;
			//System.out.println( "News is at: " + newsDir.getPath() );
		}
		// Check that at least one News directory exists and remove nulls
		boolean newsFound = false;
		//Vector nonNullNews = new Vector();
		for( int i=0; i < allNewsDirs.length; i++ ) {
			if( allNewsDirs[i] != null ) {
				newsFound = true;
				break;
			}
		}
		if( !newsFound )
		{
			//System.out.println("Could not find News directory");
			return null;
		}
		//System.out.println("News directory found");

		// Get all the mailrc files for each News directory
		File allMailrcs[] = findMailrcFiles( allNewsDirs );
		if( allMailrcs == null )
		{
			//System.out.println("Could not find mailrc files");
			return null;
		}
		//System.out.println("mailrc files found");

		Vector subscribed = new Vector();
		// Get the newsgroups in each mailrc file
		for( int i=0; i < allMailrcs.length; i++ )
		{
			File mailrc = (File) allMailrcs[i];
			NewsGroup newsgroup[] = findNewsgroups( mailrc );
			//if the Newsgroup has not already been added to the list
			for( int j=0; j < newsgroup.length; j++ )
			{
				// if newsgroup is unique then add to the list
				if( !listed( newsgroup[j], subscribed ) )
				{
					subscribed.addElement( newsgroup[j] );
				}
			}
		}

		// Copy all unique Newsgroups into the global array
		allSubscribed = new NewsGroup[ subscribed.size() ];
		subscribed.copyInto( allSubscribed );
		// Test that at least one subscribed newsgroup has been found
		if( allSubscribed.length < 1 )
		{
			//System.out.println("Could not find Subscribed newsgroups ");
			return null;
		}
		//System.out.println("Subscribed newsgroups found");

		return allSubscribed;
	}




	// Tests if the NewsGroup object has already been listed by another mailrc file
	private static boolean listed( NewsGroup newsgroup, Vector uniqueSubscription )
	{
		for(int i=0; i < uniqueSubscription.size(); i++)
		{
			NewsGroup tempGroup = (NewsGroup) uniqueSubscription.elementAt(i);
			// Test for duplication
			if(newsgroup.getHostName().equalsIgnoreCase( tempGroup.getHostName()) &&
			   newsgroup.getNewsgroupName().equalsIgnoreCase( tempGroup.getNewsgroupName() ) )
				return true;
		}
		return false;
	}




	// Finds all the NewsGroups in an individual mailrc file
	private static NewsGroup[] findNewsgroups(File mailrcfile )
	{

		String hostname = "";
		String newsgroup = "";
		NewsGroup mailrcNewsGroups[] = null;

		//Retrieve name of news host/server from file name
		//Sequentially access each of the newsgroups
		//If the newsgroup is not already contained in the global NewsGroup[] array then add it

		String filename = mailrcfile.getPath();
		if( windows )
		{
			// Windows format "staroffice-news.germany.sun.com.rc"
			int hostNameStart = filename.lastIndexOf("\\") + 1;
			int hostNameEnd = filename.indexOf(".rc");
			hostname = filename.substring( hostNameStart, hostNameEnd );
		}
		else
		{
			// Unix/Linux format "newsrc-staroffice-news.germany.sun.com"
			int hostNameStart = filename.lastIndexOf("newsrc-") + 7;
			hostname = filename.substring( hostNameStart, filename.length() );
		}

		// Assumes the content format in Window is the same as Unix/Linux (unknown at the moment)
		// i.e. a list of newsgroups each ending with a ":"
		LineNumberReader in = null;
		try {
			in = new LineNumberReader( new FileReader( mailrcfile ) );
			Vector groups = new Vector();
			String inString = "";
			int line = 0;
			while( inString != null )
			{
				in.setLineNumber( line );
				inString = in.readLine();
				line++;
				if( inString != null )
				{
					int newsgroupEnd = inString.indexOf(":");
					newsgroup = inString.substring( 0, newsgroupEnd );
					NewsGroup group = new NewsGroup( hostname, newsgroup );
					groups.addElement( group );
				}
			}
			mailrcNewsGroups = new NewsGroup[ groups.size() ];
			groups.copyInto(mailrcNewsGroups);
			in.close();
		}
		catch( IOException ioe ) {
			ioe.printStackTrace();
		}

		return mailrcNewsGroups;
	}


	// Finds all the mailrc files for all the given News directories
	private static File[] findMailrcFiles(File[] newsDirs)
	{
		Vector allFiles = new Vector();

		for( int i=0; i < newsDirs.length; i++ )
		{
			//System.out.println( "Finding mailrc for: " + newsDirs[i] );
			if( newsDirs[i] != null )
			{
				File mailrcFiles[] = newsDirs[i].listFiles( new VersionFilter() );
				if( mailrcFiles != null )
				{
					//System.out.println( "Number found: " + mailrcFiles.length );
					for( int j=0; j < mailrcFiles.length; j++ )
					{
						//System.out.println( "This mailrc was found: " + mailrcFiles[j] );
						allFiles.addElement( mailrcFiles[j] );
					}
				}
			}
		}
		File allMailrcFiles[] = new File[ allFiles.size() ];
		allFiles.copyInto(allMailrcFiles);

		//System.out.println( "number of mailrcs in total: " + allMailrcFiles.length );

		if( allMailrcFiles.length == 0 ) {
			//System.out.println( "Returning null");
			return null;
		}

		//System.out.println( "Returning an File array containing mailrcs");
		return allMailrcFiles;
	}


	// Finds all profiles belonging to one user (can be more than one)
	private static File[] findProfiles(File start)
	{
		// Get all files and directories in .mozilla
		File allFiles[] = start.listFiles();
		File[] dirs = new File[allFiles.length];
		int dirCounter = 0;

		// Remove files leaving directories only
		for(int i=0; i < allFiles.length; i++ )
		{
			if(allFiles[i].isDirectory())
			{
				dirs[dirCounter] = allFiles[i];
				dirCounter++;
			}
		}

		// Add each directory to a user profile array
		File[] profileDirs = new File[dirCounter];
		for( int i=0; i < dirCounter; i++ )
		{
			profileDirs[i] = dirs[i];
		}

		// return a File array containing the profile dirs
		return profileDirs;
	}


	// Recursively searches for the News directory for a given profile directory
        private static File findNewsDir(File start)
        {
                File mailrcFile = null;

		// File array containing all matches for the version filter ("News")
                File files[] = start.listFiles(new VersionFilter());
		// If the array is empty then no matches were found
                if (files.length == 0)
                {
			// File array of all the directories in File start
                        File dirs[] = start.listFiles(new DirFilter());
			// for each of the directories check for a match
                        for (int i=0; i< dirs.length; i++)
                        {
                                mailrcFile = findNewsDir(dirs[i]);
                                if (mailrcFile != null)
                                {
					// break the for loop
                                        break;
                                }
                        }
                }
                else
		{
			// end recursion
			// Check for a News directory inside the News directory (fix for bug)
			// Original solution had only "mailrcFile = files[0];"

			boolean noChildNews = true;
			File checkChildNewsDirs[] = files[0].listFiles(new VersionFilter());
			if( checkChildNewsDirs != null )
			{
				for( int i=0; i < checkChildNewsDirs.length; i++ )
				{
					if( checkChildNewsDirs[i].getName().equals( "News" ) )
					{
						noChildNews = false;
						break;
					}
				}
			}

			if( noChildNews )
			{
       				mailrcFile = files[0];
			}
			else
			{
				String childNewsPathName = files[0].getAbsolutePath() + System.getProperty( "file.separator" ) + "News";
				mailrcFile = new File( childNewsPathName );
			}

		}

		// return a File representing the News dir in a profile
                return mailrcFile;
	}
}



class DirFilter implements FileFilter
{
        public boolean accept(File aFile)
        {
                return aFile.isDirectory();
        }
}


class VersionFilter implements FileFilter
{
        public boolean accept(File aFile)
        {
		if( System.getProperty( "os.name" ).indexOf( "Windows" ) != -1 )
		{
			if (aFile.getName().compareToIgnoreCase("News") == 0 ||
			aFile.getName().indexOf(".rc") != -1 )
			{
				return true;
			}
		}
		else
		{
			if (aFile.getName().compareToIgnoreCase("News") == 0 ||
			aFile.getName().indexOf("newsrc") != -1 )
			{
				return true;
			}
		}

                return false;
        }
}
