package action;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import org.apache.avalon.excalibur.datasource.DataSourceComponent;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.ComponentSelector;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.Constants;
import org.apache.cocoon.Roles;
import org.apache.cocoon.acting.AbstractDatabaseAction;
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.SourceResolver;


import java.util.StringTokenizer;
import org.xml.sax.EntityResolver;


/************************************************************************
      Programmer   : Ling Kok Choon
      Last Updated : 8/8/2001
      Function     : As a path selector at Sitemap
                   : Access database to get the template( XSL ) for particular
                     web page.
 ************************************************************************/

public class PathSelector extends AbstractDatabaseAction
{
	private DataSourceComponent datasource;

	public void compose(ComponentManager manager) throws ComponentException
	{

		ComponentSelector selector = (ComponentSelector)manager.lookup( Roles.DB_CONNECTION );
		datasource = (DataSourceComponent)selector.select( "tpConnection" );
	}



   public Map act ( Redirector redirector,
   					SourceResolver resolver,
   					Map objectModel,
   					String source,
   					Parameters params)
   {
	  Map sitemapParams = new HashMap();

      //get request
	  Request request = (  Request ) objectModel.get( Constants.REQUEST_OBJECT );
      String spath = request.getServletPath();
      String srpath = request.getRequestURI();

      boolean error = false;
      boolean search = false;

      if ( spath.endsWith("/") )
      {
		   spath = spath.concat("index.xml");
	  }

      if ( srpath.endsWith("/") )
      {
		   srpath = srpath.concat("index.xml");
	  }


      String requestedFile = null;
      String requestedFileName = null ;



     // System.out.println("Servlet Path : " + spath );
     // System.out.println("Servlet Path : " + srpath );
      //System.out.println("Requested index : " + requestedIndex );

      // here to get the requested file name / group name
      StringTokenizer stringT = new StringTokenizer( spath , "/" );
     // System.out.println("countToken : " + stringT.countTokens() );
      //int tLevel = stringT.countTokens();

      while ( stringT.hasMoreTokens() )
      {
		  String t = stringT.nextToken();
		  StringTokenizer stringT1 = new StringTokenizer( t , "." );
		  //System.out.println("countToken : " + stringT1.countTokens() );
		  if ( stringT1.countTokens() == 2 )
		  {
			  requestedFileName = stringT1.nextToken();
			  requestedFile = t;
			  if ( requestedFile.toLowerCase().endsWith("_result.xml") )
			  {
				  spath = spath.substring( 0, spath.length() - "_result.xml".length()).concat(".xml") ;
				  srpath = srpath.substring( 0, srpath.length() - "_result.xml".length()).concat(".xml") ;
			  }
		  }
	  }

      //System.out.println("Servlet Path : " + spath );
      //System.out.println("Servlet Path : " + srpath );

      if ( requestedFileName == null )
      {
		  try
		  {
		     redirector.redirect ( true , srpath.concat("/index.xml") );
		  }
		  catch( Exception e )
		  {
			  System.out.println(" Error: " + e.toString() );
		  }

		  requestedFileName = "index";
		  requestedFile = "index.xml";
		  spath = spath.concat("/index.xml");
		  srpath = srpath.concat("/index.xml");
	  }

      //System.out.println("srpath : " + srpath );

      int requestedIndex = getRequestedIndex( srpath );

      //System.out.println("requestedFile : " + requestedFile );
      //System.out.println("requestedFileName : " + requestedFileName );

      String ext = srpath.substring( srpath.length() - 3 ) ;
      //System.out.println("ext : " + ext );

      String returnPath = new String() ;

      // check the path, to get the different path for different type of requested file

      if ( ext.toLowerCase().equals("gif") || ext.toLowerCase().equals("png") || ext.toLowerCase().equals("jpg") || ext.toLowerCase().equals("swf") )
      {
		 StringTokenizer st = new StringTokenizer( spath , "/" );
		 String token = null ;
		 boolean start = false;
         boolean center = true; // to check wheter the pic is for center panel
         String tempReturnPath = new String();
         String frontPath = new String();
         //String requestedFile = new String();

		 while ( st.hasMoreTokens() )
		 {
			 token = st.nextToken();

			 //to get the last token / file name
			 //if ( token.toLowerCase().endsWith(".gif") || token.toLowerCase().endsWith(".png") || token.toLowerCase().endsWith(".jpg") || token.toLowerCase().endsWith(".swf"))
			 //{
			//	 requestedFile = token;
			 //}

			 if ( token.toLowerCase().equals("pic") || token.toLowerCase().equals("templates"))
			 {
				 start = true ;
				 //System.out.println("Via 1");
			 }

             if ( token.toLowerCase().equals("menu") || token.toLowerCase().equals("sidemenu") || token.toLowerCase().equals("top") || token.toLowerCase().equals("headers") || token.toLowerCase().equals("templates"))
			 {
				 center = false ;
				 //System.out.println("Via 2");
			 }

			 if ( start )
			 {
				 tempReturnPath = tempReturnPath.concat("/").concat(token);
				 //System.out.println("tempReturnPath: " + tempReturnPath);
			 }
			 else
			 {
				 //get the path in front of the pic path
				 frontPath = frontPath.concat("/").concat(token);
				 //System.out.println("frontPath: " + frontPath);
			 }
		 }

		 if ( center == false )
		 {
			 returnPath = tempReturnPath;
			 //System.out.println("returnPathA: " + returnPath);
		 }
		 else
		 {
			 returnPath = "/pic".concat(frontPath).concat("/").concat( requestedFile );
			 //System.out.println("returnPathB: " + returnPath);
		 }

		 //cut the first / char
		 returnPath = returnPath.substring(1);
	  }
	  else if ( ext.toLowerCase().equals("xml") ) // the xml request will return the *.agg ( aggregation )
	  {
		  try
		  {
		  	String skel = params.getParameter("skel");
		  	//System.out.println("skel : " + skel );

            //System.out.println("requestedIndex : " + requestedIndex );
            String parentIndexS =  getGroupInfo( requestedIndex , "PARENT_ID" ) ;
            System.out.println("parentIndexS : " + parentIndexS );
            if ( parentIndexS != null && parentIndexS.length() > 0 )
            {
                int parentIndex =  Integer.parseInt ( parentIndexS );
                String label =  getGroupInfo( requestedIndex , "LABEL" );
		  	    if ( skel.equals("true") ) // means that is the outter xsl ( agg ) request
		  	    {

			    	if ( getGroupInfo( parentIndex , "GROUP_TYPE" ).equals("NEWSDIR") && label.equals("index") )
			    	{
			    		//System.out.println("via1");
			    	    returnPath = "/news.xsp";
			    	}
			    	else if ( getGroupInfo( parentIndex , "GROUP_TYPE" ).equals("NEWSDIR") && label.equals("archive") )
			    	{
			    		//System.out.println("via1");
			    	    returnPath = "/archive.xsp";
			    	}
			    	else if ( requestedFile.toLowerCase().endsWith("_result.xml") )
			    	{
						returnPath = "/".concat(requestedFileName).concat(".frm");
					}
					else
			    	{
			    		returnPath = (spath.substring( 0 , spath.length() - 3)).concat("agg");
			   		//System.out.println("via4");
			    	}
			    }
			    else
			    {
			    	if ( getGroupInfo( parentIndex , "GROUP_TYPE" ).equals("NEWSDIR") && label.equals("index"))
			    	{
					    //System.out.println("via2");
					    returnPath = "";
				    }
				    else
				    {
				        returnPath = ("/xml").concat( ( spath.substring( 0 , spath.length() - 4 ) ) ).concat("_final.xml");
				        //System.out.println("via3");
				   }
			    }
			}
			else
			{
  	    	    if ( requestedFile.equals("search_swish.xml") )
			    {
					returnPath = "/search_swish.xsp";
					search = true ;
				}
				else
				{
					returnPath="";
				}
			}


	  	  }
	  	  catch( Exception e )
	  	  {
			  e.printStackTrace();
		  }

		  //cut the first / char
		  if ( returnPath.length() > 0 )
		  {
		  	returnPath = returnPath.substring(1);
		  }
	  }
	  else if ( ext.toLowerCase().equals(".js") )
	  {
		  StringTokenizer st = new StringTokenizer( spath , "/" );
		  String token = null ;
		  boolean start = false;

		  while ( st.hasMoreTokens() )
		  {
		 	 token = st.nextToken();
		 	 if ( token.toLowerCase().equals("js") )
		 	 {
		 		 start = true ;
		 	 }

		 	 if ( start )
		 	 {
		 		 returnPath = returnPath.concat("/").concat(token);
		 	 }
		  }

		  //cut the first / char
		 returnPath = returnPath.substring(1);

	  }
	  else if ( ext.toLowerCase().equals("css") )
	  {
	  		  StringTokenizer st = new StringTokenizer( spath , "/" );
	  		  String token = null ;
	  		  boolean start = false;

	  		  while ( st.hasMoreTokens() )
	  		  {
	  		 	 token = st.nextToken();
	  		 	 if ( token.toLowerCase().equals("css") )
	  		 	 {
	  		 		 start = true ;
	  		 	 }

	  		 	 if ( start )
	  		 	 {
	  		 		 returnPath = returnPath.concat("/").concat(token);
	  		 	 }
	  		  }

	  		  //cut the first / char
	  		 returnPath = returnPath.substring(1);
	  }
      else if ( ext.toLowerCase().equals("rtf") || ext.toLowerCase().equals("doc") || ext.toLowerCase().equals("pdf") )
	  {
		  returnPath = spath.substring(1) ;
	  }
      else if ( ext.toLowerCase().equals("tml") || ext.toLowerCase().equals("htm"))
	  {
		  returnPath = spath.substring(1) ;
	  }
	  else // error
	  {
		    error = true;
			sitemapParams.put("navigation_path", "resource_not_found.err" );
			sitemapParams.put("banner_path", "resource_not_found.err" );
			sitemapParams.put("path", "resource_not_found.err" );
			sitemapParams.put("link_path", "resource_not_found.err" );
			sitemapParams.put("side_menu_path", "resource_not_found.err" );
			sitemapParams.put("foot_note_path", "resource_not_found.err" );
			sitemapParams.put("aggXSLPath" , "templates/output_xsl/resource_not_found.xsl");
	  }

      if ( !error )
      {
      //create the xsl path, same name with the request,
      //need to be db call in Brel CMS
      	String xslPath = (spath.substring( 0, spath.length() - 3 )).concat("xsl");
      //String rpath = request.getRequestURI();

      //System.out.println("returnPath : " + returnPath );

      //return the servlet path e.g /path/Hello.xml
      	sitemapParams.put("path", returnPath );
        System.out.println("path:" + returnPath );
      }

      if ( ext.toLowerCase().equals("xml") )
      {


          if ( search )
          {
				sitemapParams.put("navigation_path", "navigate.nv" );
				sitemapParams.put("banner_path", "banner.br" );
				sitemapParams.put("link_path", "links.ls" );
				sitemapParams.put("foot_note_path", "foot_note.fn" );
				sitemapParams.put("aggXSLPath" , "templates/output_xsl/tpt1_agg.xsl" );
				sitemapParams.put("side_menu_path", "side_menu.sm" );
				sitemapParams.put("centerXSLPath", "stylesheet/search_swish.xsl" );
		  }
          else
          {
          	//System.out.println("centerPath:" + centerPath );
          	//System.out.println("type:" + getGroupInfo( requestedIndex , "STATUS" ) );
    	  	 String centerPath = getXSLPath( "OUTPUT_XSL" , requestedIndex );
    	  	 String agg_xsl = getXSLPath( "AGG_XSL" , requestedIndex );
          	 String template_type = getXSLPath( "TEMPLATE_TYPE" , requestedIndex );

      	  	 if ( getCreatedPage( requestedIndex ) && !getGroupInfo( requestedIndex , "STATUS" ).equals("DELETED") && centerPath != null )
      	  	 {
				//System.out.println("via");

				if ( template_type.equals("content") )
				{
					sitemapParams.put("navigation_path", "navigate.nv" );
					sitemapParams.put("banner_path", "banner.br" );
					sitemapParams.put("link_path", "links.ls" );
					sitemapParams.put("foot_note_path", "foot_note.fn" );
		  		}
		    	else if (template_type.equals("home") )
		    	{
					sitemapParams.put("banner_path", "home_banner.hbr" );
					sitemapParams.put("navigation_path", "importantL.il" );
					sitemapParams.put("link_path", "news.ns" );
					sitemapParams.put("foot_note_path", "foot_note.fn" );
				}

				sitemapParams.put("aggXSLPath" , agg_xsl );
				sitemapParams.put("side_menu_path", "side_menu.sm" );
				String centerXSLPath = formatPath( centerPath );
				sitemapParams.put("centerXSLPath", centerXSLPath );
		   		System.out.println("centerXSLPath : " + centerXSLPath );
			}
			else
			{
				System.out.println("via");
				sitemapParams.put("navigation_path", "resource_not_found.err" );
				sitemapParams.put("banner_path", "resource_not_found.err" );
				sitemapParams.put("path", "resource_not_found.err" );
				sitemapParams.put("link_path", "resource_not_found.err" );
				sitemapParams.put("side_menu_path", "resource_not_found.err" );
				sitemapParams.put("foot_note_path", "resource_not_found.err" );
				sitemapParams.put("aggXSLPath" , "templates/output_xsl/resource_not_found.xsl");
			}
		}
	  }


	  //request.setAttribute ( "path", spath );

	  return sitemapParams;
  }




  //get group_index / group name from the requested fine name
  public int getRequestedIndex ( String path )
  {

     int returnIndex = 0 ;


  	 if ( path == null || path.length() == 0)
     {
		//System.out.println("path:" + path );
  	    return (0);
  	 }
  	else
  	{


       String query = "select GROUP_ID, PATH from group_ext";

  	   try
  	   {

		   Connection con  = datasource.getConnection();
		   Statement  stat  = con.createStatement();
           ResultSet rs = null ;
           int group_id = 0 ;
           String group_path = null ;

  		   rs = stat.executeQuery ( query );

           while ( rs.next() )
     	   {
			    group_id = rs.getInt(1);
				group_path = rs.getString(2);


                StringTokenizer st = new StringTokenizer ( group_path , "/" );
                boolean start = false;
                String result = new String() ;

                while ( st.hasMoreTokens() )
                {
     			   String token = st.nextToken();
      			   if ( token.toLowerCase().equals("webapps") )
     			   {
     				   start = true;
     			   }
     			   else
     			   {
    				   if ( start )
    				   {
    					   result = result.concat("/").concat(token);
    				   }
    			   }
    		   }


                //System.out.println("result:" + result.concat(".xml") );
                //System.out.println("path:" + path );
				//System.out.println("result:" + result );
				if ( path.equals(result.concat(".xml")) )
				{
					//System.out.println("here:" + path );
					returnIndex = group_id;
				}
		   }

           rs.close();
           stat.close();
           con.close();

  	 }
  	 catch( Exception e )
  	 {
  		 System.out.println("getRequestedIndex error:" + e.toString() );
  	 }

    //System.out.println("returnIndex:" + returnIndex );

  	return ( returnIndex );
  	}


  }

  //this function to format the path or to cut the infont part of path start from "webapps"
  public String formatPath ( String inputPath )
  {
	  StringTokenizer st = new StringTokenizer( inputPath , "/" );
	  boolean start = false ;
	  String result = new String();

	  while ( st.hasMoreTokens() )
	  {
		String token = st.nextToken();
		if ( token.toLowerCase().equals("templates") )
		{
			start = true ;
		}

        if ( start )
		{
			result = result.concat("/").concat(token);
		}
	  }

	  return ( result.substring(1) );
  }

  //this function check the requested xml is it created or not
  public boolean getCreatedPage( int group_id )
    {
		String query = "select TEMPLATE_NAME from TURBINE_GROUP tg,TEMPLATE tt, TEMPLATE_SELECTION t2 " +
		                      "where tg.GROUP_ID=t2.GROUP_ID and tt.TEMPLATE_ID=t2.TEMPLATE_ID and tg.GROUP_ID=" + group_id;

        boolean returnB = false;
		try
		{
			Connection con  = datasource.getConnection();
			Statement  stat  = con.createStatement();
        	ResultSet rs = null ;

		    rs = stat.executeQuery ( query );

			if ( rs.next() )
			{
				returnB = true;
			}
			else
			{
				returnB = false ;
			}

			rs.close();
			stat.close();
			con.close();
		}
		catch ( Exception e )
		{
		  System.out.println( e.toString() );
		}


	   	return ( returnB );
	}


    /**
      This method return the level of a index
      last modified: 29-8-2001

    public int getLevel( String index )
	{
	   if ( index.equals("1") )
	   {
			  return ( 1 );
	   }
	   else
	   {
		  StringTokenizer st = new StringTokenizer( index , "." );
		  return ( st.countTokens() );
	   }
	}
  */


  public String getXSLPath( String option , int group_id )
  {

      String result = null ;
      if ( group_id == 0 )
      {
	  }
	  else
	  {
	  	try
	  	{
	  		Connection con  = datasource.getConnection();
	  		Statement  stat  = con.createStatement();
      	    ResultSet rs = null ;


      	    //option will be INPUT_XSL or OUTPUT_XSL
            String query = "select " + option + " from TURBINE_GROUP tg,TEMPLATE tt, TEMPLATE_SELECTION t2 " +
		              "where tg.GROUP_ID=t2.GROUP_ID and tt.TEMPLATE_ID=t2.TEMPLATE_ID and tg.GROUP_ID=" + group_id;

			rs = stat.executeQuery ( query );

			while ( rs.next() )
			{
				result = rs.getString(1);
			}

			//System.out.println("Result : " + result );
			//System.out.println("group_id : " + group_id );

      	  rs.close();
      	  stat.close();
      	  con.close();

	  	}
	  	catch( SQLException sqle )
	  	{
			  System.out.println( sqle.toString() );
	  	}
  	  }

      return ( result );

  }


  //this function get the group's info
  public String getGroupInfo( int group_id , String type )
  {

    String result = null;

  	if ( group_id == 0 )
  	{
  	    return "";
  	}
  	else
  	{
       String query = "select " + type +"  from group_ext where group_id=" + group_id;

  	   try
  	   {

		   Connection con  = datasource.getConnection();
		   Statement  stat  = con.createStatement();
           ResultSet rs = null ;

  		   rs = stat.executeQuery ( query );

           while ( rs.next() )
     	   {
				result = rs.getString(1);
		   }

           rs.close();
           stat.close();
           con.close();

  	    }
  	    catch( Exception e )
  	    {
	    	 System.out.println("getGroupInfo exception : " + e.toString() );
  	    }
     }

  	return ( result );
   }

}