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

package org.apache.bsf.util;

import java.beans.Introspector;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.StringTokenizer;
import java.util.Vector;

/**
 * Deals with strings (probably need to elaborate some more).
 *
 * @author   Matthew J. Duftler
 */
public class StringUtils
{
  public static final String lineSeparator =
    System.getProperty("line.separator", "\n");
  public static final String lineSeparatorStr = cleanString(lineSeparator);

  public static String classNameToVarName(String className)
  {
    // Might represent an array.
    int arrayDim = 0;

    while (className.endsWith("[]"))
    {
      className = className.substring(0, className.length() - 2);
      arrayDim++;
    }

    int    iLastPeriod = className.lastIndexOf('.');
    String varName     = Introspector.decapitalize(
                                         iLastPeriod != -1
                                         ? className.substring(iLastPeriod + 1)
                                         : className);

    if (arrayDim > 0)
    {
      varName += "_" + arrayDim + "D";
    }

    return getValidIdentifierName(varName);
  }
  // Ensure that escape sequences are passed through properly.
  public static String cleanString(String str)
  {
    if (str == null)
      return null;
    else
    {
      char[]       charArray = str.toCharArray();
      StringBuffer sBuf      = new StringBuffer();
      
      for (int i = 0; i < charArray.length; i++)
        switch (charArray[i])
        {
          case '\"' : sBuf.append("\\\"");
					  break;
		  case '\\' : sBuf.append("\\\\");
					  break;
		  case '\n' : sBuf.append("\\n");
					  break;
		  case '\r' : sBuf.append("\\r");
					  break;
		  default   : sBuf.append(charArray[i]);
					  break;
		}
	  
	  return sBuf.toString();
	}
  }
  /**
   * Get a string consisting of <code>numberOfChars</code> theChars.
   *
   * @return a string consisting of <code>numberOfChars</code> theChars.
   */
  public static String getChars(int numberOfChars, char theChar)
  {
	if (numberOfChars <= 0)
	  return "";

	StringBuffer sRet = new StringBuffer(numberOfChars);

	for (int i = 0; i < numberOfChars; i++)
	  sRet.append(theChar);     

	return sRet.toString();
  }
  /*
	This method will return the correct name for a class object representing
	a primitive, a single instance of a class, as well as n-dimensional arrays
	of primitives or instances. This logic is needed to handle the string returned
	from Class.getName(). If the class object represents a single instance (or
	a primitive), Class.getName() returns the fully-qualified name of the class
	and no further work is needed. However, if the class object represents an
	array (of n dimensions), Class.getName() returns a Descriptor (the Descriptor
	grammar is defined in section 4.3 of the Java VM Spec). This method will
	parse the Descriptor if necessary.
  */
  public static String getClassName(Class targetClass)
  {
	String className = targetClass.getName();

	return targetClass.isArray() ? parseDescriptor(className) : className;
  }
  public static String getCommaListFromVector(Vector sourceVector)
  {
	StringBuffer strBuf = new StringBuffer();

	for (int i = 0; i < sourceVector.size(); i++)
	{
	  strBuf.append((i > 0 ? ", " : "") +
					sourceVector.elementAt(i));
	}

	return strBuf.toString();
  }
  /*
	Returns a Reader for reading from the specified resource, if the resource
	points to a stream.
  */
  public static Reader getContentAsReader(URL url) throws SecurityException,
														  IllegalArgumentException,
														  IOException
  {
	if (url == null)
	{
	  throw new IllegalArgumentException("URL cannot be null.");
	}

	try
	{
	  Object content = url.getContent();

	  if (content == null)
	  {
		throw new IllegalArgumentException("No content.");
	  }

	  if (content instanceof InputStream)
	  {
		Reader in = new InputStreamReader((InputStream)content);

		if (in.ready())
		{
		  return in;
		}
		else
		{
		  throw new FileNotFoundException();
		}
	  }
	  else
	  {
		throw new IllegalArgumentException((content instanceof String)
										   ? (String)content
										   : "This URL points to a: " +
											 StringUtils.getClassName(content.getClass()));
	  }
	}
	catch (SecurityException e)
	{
	  throw new SecurityException("Your JVM's SecurityManager has disallowed this.");
	}
	catch (FileNotFoundException e)
	{
	  throw new FileNotFoundException("This file was not found: " + url);
	}
  }
  /*
	Shorthand for: IOUtils.getStringFromReader(getContentAsReader(url)).
  */
  public static String getContentAsString(URL url) throws SecurityException,
														  IllegalArgumentException,
														  IOException
  {
	return IOUtils.getStringFromReader(getContentAsReader(url));
  }
  // Handles multi-line strings.
  public static String getSafeString(String scriptStr)
  {
	BufferedReader in           = new BufferedReader(new StringReader(scriptStr));
	StringBuffer   strBuf       = new StringBuffer();
	String         tempLine,
				   previousLine = null;

	try
	{
	  while ((tempLine = in.readLine()) != null)
	  {
		if (previousLine != null)
		{
		  strBuf.append("\"" + previousLine + lineSeparatorStr + "\" +" +
						lineSeparator);
		}

		previousLine = cleanString(tempLine);
	  }
	}
	catch (IOException e)
	{
	}      

	strBuf.append("\"" + (previousLine != null ? previousLine : "") + "\"" +
				  lineSeparator);

	return strBuf.toString();
  }
  /*
  */
  public static URL getURL(URL contextURL, String spec) throws MalformedURLException
  {
	return getURL(contextURL, spec, 1);
  }
  /*
	The recursiveDepth argument is used to insure that the algorithm gives up
	after hunting 2 levels up in the contextURL's path.
  */
  private static URL getURL(URL contextURL, String spec, int recursiveDepth)
                                                  throws MalformedURLException
  {
    URL url = null;

    try
    {
      url = new URL(contextURL, spec);

      try
      {
        url.openStream();
      }
      catch (IOException ioe1)
      {
        throw new MalformedURLException("This file was not found: " + url);
      }
    }
    catch (MalformedURLException e1)
    {
      url = new URL("file", "", spec);

      try
      {
        url.openStream();
      }
      catch (IOException ioe2)
      {
        if (contextURL != null)
        {
          String contextFileName = contextURL.getFile();
          String parentName      = new File(contextFileName).getParent();

          if (parentName != null && recursiveDepth < 3)
          {
            return getURL(new URL("file", "", parentName + '/'),
                          spec,
                          recursiveDepth + 1);
          }
        }

        throw new MalformedURLException("This file was not found: " + url);
      }
    }

    return url;
  }
  public static String getValidIdentifierName(String identifierName)
  {
    if (identifierName == null || identifierName.length() == 0)
      return null;

    StringBuffer strBuf = new StringBuffer();

    char[] chars = identifierName.toCharArray();

    strBuf.append(Character.isJavaIdentifierStart(chars[0])
                  ? chars[0]
                  : '_'
                 );

    for (int i = 1; i < chars.length; i++)
    {
      strBuf.append(Character.isJavaIdentifierPart(chars[i])
                    ? chars[i]
                    : '_'
                   );
    }

    return strBuf.toString();
  }
  public static boolean isValidIdentifierName(String identifierName)
  {
    if (identifierName == null || identifierName.length() == 0)
      return false;

    char[] chars = identifierName.toCharArray();

    if (!Character.isJavaIdentifierStart(chars[0]))
      return false;

    for (int i = 1; i < chars.length; i++)
      if (!Character.isJavaIdentifierPart(chars[i]))
        return false;

    return true;
  }
  public static boolean isValidPackageName(String packageName)
  {
    if (packageName == null)
      return false;
    else if (packageName.length() == 0)
      // Empty is ok.
      return true;

    StringTokenizer strTok = new StringTokenizer(packageName, ".", true);

    // Should have an odd number of tokens (including '.' delimiters).
    if (strTok.countTokens() % 2 != 1)
      return false;

    // Must start with a valid identifier name.
    if (!isValidIdentifierName(strTok.nextToken()))
      return false;

    // ... followed by 0 or more of ".ValidIdentifier".
    while (strTok.hasMoreTokens())
    {
      // Must be a '.'.
      if (!strTok.nextToken().equals("."))
        return false;

      // Must be a valid identifier name.
      if (strTok.hasMoreTokens())
      {
        if (!isValidIdentifierName(strTok.nextToken()))
          return false;
      }
      else
        return false;
    }

    return true;
  }
  /*
    See the comment above for getClassName(targetClass)...
  */
  private static String parseDescriptor(String className)
  {
    char[] classNameChars = className.toCharArray();
    int    arrayDim       = 0;
    int    i              = 0;

    while (classNameChars[i] == '[')
    {
      arrayDim++;
      i++;
    }

    StringBuffer classNameBuf = new StringBuffer();

    switch (classNameChars[i++])
    {
      case 'B' : classNameBuf.append("byte");
                 break;
      case 'C' : classNameBuf.append("char");
                 break;
      case 'D' : classNameBuf.append("double");
                 break;
      case 'F' : classNameBuf.append("float");
                 break;
      case 'I' : classNameBuf.append("int");
                 break;
      case 'J' : classNameBuf.append("long");
                 break;
      case 'S' : classNameBuf.append("short");
                 break;
      case 'Z' : classNameBuf.append("boolean");
                 break;
      case 'L' : classNameBuf.append(classNameChars,
                                     i, classNameChars.length - i - 1);
                 break;
    }

    for (i = 0; i < arrayDim; i++)
      classNameBuf.append("[]");

    return classNameBuf.toString();
  }
}
