/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (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.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Community System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.htmlcheck.filters;

import java.net.*;
import java.util.*;
import org.apache.log4j.Logger;
import org.apache.regexp.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.htmlcheck.Rewriter;
import com.silverwrist.venice.htmlcheck.RewriterServices;
import com.silverwrist.venice.htmlcheck.MarkupData;

public class URLRewriter implements Rewriter
{
  /*--------------------------------------------------------------------------------
   * Internal class containing URL elements.
   *--------------------------------------------------------------------------------
   */

  private static class URLElement
  {
    private REProgram m_match;
    private String m_prefix;

    URLElement(String pattern, String prefix)
    {
      try
      { // fill the classes
	m_match = COMPILER.compile(pattern);
	m_prefix = prefix;

      } // end try
      catch (RESyntaxException e)
      { // shouldn't happen
	logger.fatal("got RESyntaxException in URLElement",e);

      } // end catch

    } // end constructor

    String eval(String input)
    {
      RE m = new RE(m_match,RE.MATCH_CASEINDEPENDENT);
      if (m.match(input))
	return m_prefix + input;
      else
	return null;

    } // end eval

  } // end class URLElement

  /*--------------------------------------------------------------------------------
   * Static data members
   *--------------------------------------------------------------------------------
   */

  private static Logger logger = Logger.getLogger(URLRewriter.class);

  private static final RECompiler COMPILER = new RECompiler();
  private static final String[] SETUP_DATA =
    {
      "^http://[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)+",                                 "",
      "^ftp://[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)+",                                  "",
      "^gopher://[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)+",                               "",
      "^mailto:[A-Za-z0-9!#$%*+-/=?^_`{|}~.]+@[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)+$", "",
      "^news:[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)+$",                                  "",
      "^nntp://[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)+",                                 "",
      "^telnet://[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)+",                               "",
      "^tn3270://[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)+",                               "",
      "^www\\.[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)*",                                  "http://",
      "^ftp\\.[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)*",                                  "ftp://",
      "^gopher\\.[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)*",                               "gopher://"
    };

  private static final List KNOWN_ELEMENTS;

  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  public URLRewriter()
  { // do nothing
  } // end constructor

  /*--------------------------------------------------------------------------------
   * Implementations from interface Rewriter
   *--------------------------------------------------------------------------------
   */

  public String getName()
  {
    return null;

  } // end getName

  public MarkupData rewrite(String data, RewriterServices svc)
  {
    for (Iterator it=KNOWN_ELEMENTS.iterator(); it.hasNext(); )
    { // test each element in turn
      URLElement ue = (URLElement)(it.next());
      String s = ue.eval(data);
      if (s!=null)
      { // got a match!  record the external reference and build the open <A> tag
	try
	{ // create URL and add it
	  if (s.toLowerCase().startsWith("http:"))
	    svc.addExternalReference(new URL(s));

	} // end try
	catch (MalformedURLException e)
	{ // forget it
	} // end catch

	StringBuffer open_a = new StringBuffer("<a href=\"");
	open_a.append(s).append("\"");
	String catenate = svc.getRewriterAttrValue("ANCHORTAIL");
	if (!(StringUtil.isStringEmpty(catenate)))
	  open_a.append(' ').append(catenate);
	open_a.append('>');

	// here's how you mark it up!
	return new MarkupData(open_a.toString(),data,"</a>");

      } // end if

    } // end for

    return null;  // sorry, no can do

  } // end rewrite

  /*--------------------------------------------------------------------------------
   * Static initializer
   *--------------------------------------------------------------------------------
   */

  static
  {
    ArrayList tmp = new ArrayList();
    for (int i=0; i<SETUP_DATA.length; i+=2)
      tmp.add(new URLElement(SETUP_DATA[i],SETUP_DATA[i + 1]));
    tmp.trimToSize();
    KNOWN_ELEMENTS = Collections.unmodifiableList(tmp);

  } // end static initializer

} // end class URLRewriter
