/*******************************************************************************
 * Copyright (c) 2002-2005 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   IBM - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.wsi.internal.core.util;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Vector;

/**
 * This class checks the cookies conform to RFC2965.
 * 
 * @author Baltak
 */
public class SetCookie2Validator
{

  private Vector commentVect = new Vector();
  private Vector commentURLVect = new Vector();
  private Vector domainVect = new Vector();
  private Vector max_AgeVect = new Vector();
  private Vector pathVect = new Vector();
  private Vector portVect = new Vector();
  private Vector versionVect = new Vector();

  private boolean comment = false;
  private boolean commentURL = false;
  private boolean domain = false;
  private boolean max_age = false;
  private boolean path = false;
  private boolean port = false;
  private boolean version = false;

  /**
   * Method resetFlags.
   */
  private void resetFlags()
  {
    comment = false;
    commentURL = false;
    domain = false;
    max_age = false;
    path = false;
    port = false;
    version = false;
  }

  /**
   * Check if the string satisfy the "Set-Cookie2" header value.
   * @param str String 
   * @return boolean
   */
  public boolean isSetCookie2(String str)
  {

    try
    {
      int index = 0;
      int newIndex = 0;
      while (true)
      {
        newIndex = getLastCookie(str, index);
        if (index == newIndex)
          return false;
        // skip spaces
        index = newIndex;
        index = skipSpaces(str, index);
        if (index == str.length())
        {
          return true;
        }
        else
        {
          if (str.charAt(index) != ',')
            return false;
          index++;
          // skip spaces
          index = skipSpaces(str, index);
        }

      }
    }
    catch (Throwable th)
    {
      return false;
    }

  }

  /**
   * Method getLastCookie.
   * @param str
   * @param startIndex
   * @return int
   */
  private int getLastCookie(String str, int startIndex)
  {

    resetFlags();

    int index = startIndex;
    // find token
    int newIndex = BasicRules.getLastToken(str, index);
    if (index == newIndex)
      return startIndex;

    index = newIndex;
    if (index == str.length())
      return startIndex;

    // if not '=' - error
    if (str.charAt(index) != '=')
      return startIndex;

    index++;
    if (index == str.length())
      return startIndex;

    // get value
    newIndex = getLastValue(str, index);
    if (index == newIndex)
      return startIndex;

    while (true)
    {
      index = newIndex;
      if (index == str.length())
        return index;

      if (str.charAt(index) != ';')
        return index;
      index++;
      // skip spaces
      index = skipSpaces(str, index);

      if (index == str.length())
        return startIndex;
      newIndex = getLastSetCookieAv(str, index);
      if (index == newIndex)
        return startIndex;
    }
  }

  /**
   * Method getLastValue.
   * @param str
   * @param startIndex
   * @return int
   */
  private int getLastValue(String str, int startIndex)
  {

    int index = BasicRules.getLastToken(str, startIndex);
    if (index != startIndex)
      return index;
    index = BasicRules.getLastQuotedString(str, startIndex);
    if (index != startIndex)
      return index;

    return startIndex;
  }

  /**
   * Method getLastSetCookieAv.
   * @param str
   * @param startIndex
   * @return int
   */
  private int getLastSetCookieAv(String str, int startIndex)
  {

    int index = startIndex;
    int newIndex = 0;

    String token = str.substring(index, BasicRules.getLastToken(str, index));

    if (str.startsWith("Comment=", index))
    {
      index += "Comment=".length();
      newIndex = getLastValue(str, index);
      if (index == newIndex)
        return startIndex;
      // debug ->
      String qqq = getValue(str, index, newIndex);
      commentVect.add(qqq);
      // debug <-
      comment = true;
      return newIndex;
    }
    else if (str.startsWith("CommentURL=", index))
    {
      index += "CommentURL=".length();

      if (str.charAt(index) != '\"')
        return startIndex;

      newIndex = str.indexOf('\"', index + 1);
      if (newIndex == -1)
        return startIndex;
      try
      {
        URL url = new URL(str.substring(index + 1, newIndex));
      }
      catch (MalformedURLException mue)
      {
        return startIndex;
      }
      // debug ->
      String qqq = getValue(str, index + 1, newIndex);
      commentURLVect.add(qqq);
      // debug <-
      newIndex++;
      commentURL = true;
      return newIndex;
    }
    else if (str.startsWith("Discard", index))
    {
      return startIndex + "Discard".length();
    }
    else if (str.startsWith("Domain=", index))
    {
      index += "Domain=".length();

      newIndex = getLastValue(str, index);
      if (index == newIndex)
        return startIndex;

      // debug ->
      String qqq = getValue(str, index, newIndex);
      domainVect.add(qqq);
      // debug <-
      domain = true;
      return newIndex;
    }
    else if (str.startsWith("Max-Age=", index))
    {
      index += "Max-Age=".length();

      newIndex = getLastValue(str, index);
      if (index == newIndex)
        return startIndex;

      String qqq = getValue(str, index, newIndex);
      try
      {
        Integer.parseInt(qqq);
      }
      catch (NumberFormatException nfe)
      {
        return startIndex;
      }
      // debug ->
      max_AgeVect.add(qqq);
      // debug <-
      max_age = true;
      return newIndex;
    }
    else if (str.startsWith("Path=", index))
    {
      index += "Path=".length();

      newIndex = getLastValue(str, index);
      if (index == newIndex)
        return startIndex;

      String qqq = getValue(str, index, newIndex);
      if (path == false)
        pathVect.add(qqq);
      path = true;
      return newIndex;
    }
    else if (str.startsWith("Port", index))
    {
      index += "Port".length();
      port = true;
      if (str.charAt(index) != '=')
        return index;

      index++;
      if (str.charAt(index) != '\"')
        return startIndex;

      index++;
      newIndex = getLastPortList(str, index);
      if (index == newIndex)
        return startIndex;

      // debug ->
      String qqq = getValue(str, index, newIndex);
      portVect.add(qqq);
      // debug <-

      index = newIndex;
      if (str.charAt(index) != '\"')
        return startIndex;
      index++;
      return index;

    }
    else if (str.startsWith("Secure", index))
    {
      return startIndex + "Secure".length();
    }
    else if (str.startsWith("Version=", index))
    {
      index += "Version=".length();

      newIndex = getLastDIGIT(str, index);
      if (index == newIndex)
        return startIndex;

      // debug ->
      String qqq = getValue(str, index, newIndex);
      versionVect.add(qqq);
      // debug <-
      version = true;
      return newIndex;
    }
    else
    {
      return startIndex;
    }
  }

  /**
   * Method getLastPortList.
   * @param str
   * @param startIndex
   * @return int
   */
  private int getLastPortList(String str, int startIndex)
  {
    int index = startIndex;
    int newIndex = 0;

    while (true)
    {
      newIndex = getLastDIGIT(str, index);
      if (index == newIndex)
        return startIndex;

      index = newIndex;
      if (str.charAt(index) != ',')
        return index;
      index++;
    }
  }

  /**
   * Method getLastDIGIT.
   * @param str
   * @param startIndex
   * @return int
   */
  private int getLastDIGIT(String str, int startIndex)
  {
    int index = startIndex;
    for (; index < str.length(); index++)
    {
      if (!BasicRules.isDIGIT(str.charAt(index)))
        return index;
    }
    return index;
  }

  /**
   * Check if the string satisfy the "Cookie" header value.
   * @param str String
   * @return boolean
   */
  public boolean isCookie(String str)
  {
    int index = 0;
    int newIndex = 0;

    try
    {
      newIndex = getLastVersion(str, index);
      if (index == newIndex)
        return false;

      index = newIndex;
      index = skipSpaces(str, index);
      if (str.charAt(index) != ';' && str.charAt(index) != ',')
        return false;

      index++;
      index = skipSpaces(str, index);

      while (true)
      {
        newIndex = getLastCookiesValue(str, index);
        if (index == newIndex)
          return false;

        index = newIndex;
        if (index == str.length())
          return true;

        if (str.charAt(index) != ';' && str.charAt(index) != ',')
          return false;
        index++;
        index = skipSpaces(str, index);
      }
    }
    catch (Throwable th)
    {
      return false;
    }
  }

  /**
   * Method getLastVersion.
   * @param str
   * @param startIndex
   * @return int
   */
  private int getLastVersion(String str, int startIndex)
  {
    int index = startIndex;
    int newIndex = 0;
    if (!str.startsWith("$Version="))
      return startIndex;
    index += "$Version=".length();
    newIndex = getLastValue(str, index);
    if (index == newIndex)
      return startIndex;

    return newIndex;
  }

  /**
   * Method getLastCookiesValue.
   * @param str
   * @param startIndex
   * @return int
   */
  private int getLastCookiesValue(String str, int startIndex)
  {
    int index = startIndex;
    int newIndex = 0;
    int oldIndex = 0;

    // find token
    newIndex = BasicRules.getLastToken(str, index);
    if (index == newIndex)
      return startIndex;

    index = newIndex;
    if (index == str.length())
      return startIndex;

    // if not '=' - error
    if (str.charAt(index) != '=')
      return startIndex;

    index++;
    if (index == str.length())
      return startIndex;

    // get value
    newIndex = getLastValue(str, index);
    if (index == newIndex)
      return startIndex;

    index = newIndex;
    if (index == str.length())
      return index;

    if (str.charAt(index) != ';')
      return index;

    // process [";" path] [";" domain] [";" port] 
    oldIndex = index;
    index++;
    if (index == str.length())
      return startIndex;

    index = skipSpaces(str, index);
    if (index == str.length())
      return startIndex;

    // process path
    newIndex = getLastPath(str, index);
    if (index != newIndex)
    {
      index = newIndex;
      if (index == str.length())
        return index;

      if (str.charAt(index) != ';')
        return index;

      oldIndex = index;
      index++;
      if (index == str.length())
        return startIndex;

      index = skipSpaces(str, index);
      if (index == str.length())
        return startIndex;

    }

    // process domain
    newIndex = getLastDomain(str, index);
    if (index != newIndex)
    {
      index = newIndex;
      if (index == str.length())
        return index;

      if (str.charAt(index) != ';')
        return index;

      oldIndex = index;
      index++;
      if (index == str.length())
        return startIndex;

      index = skipSpaces(str, index);
      if (index == str.length())
        return startIndex;

    }

    // process port
    newIndex = getLastPort(str, index);
    if (index != newIndex)
      return newIndex;
    else
      return oldIndex;
  }

  /**
   * Method getLastPath.
   * @param str
   * @param startIndex
   * @return int
   */
  private int getLastPath(String str, int startIndex)
  {
    int index = startIndex;
    int newIndex = 0;

    if (!str.startsWith("$Path=", index))
      return startIndex;
    index += "$Path=".length();
    newIndex = getLastValue(str, index);
    if (index == newIndex)
      return startIndex;

    return newIndex;
  }

  /**
   * Method getLastDomain.
   * @param str
   * @param startIndex
   * @return int
   */
  private int getLastDomain(String str, int startIndex)
  {
    int index = startIndex;
    int newIndex = 0;

    if (!str.startsWith("$Domain=", index))
      return startIndex;
    index += "$Domain=".length();
    newIndex = getLastValue(str, index);
    if (index == newIndex)
      return startIndex;

    return newIndex;
  }

  /**
   * Method getLastPort.
   * @param str
   * @param startIndex
   * @return int
   */
  private int getLastPort(String str, int startIndex)
  {
    int index = startIndex;
    int newIndex = 0;

    if (!str.startsWith("$Port", index))
      return startIndex;

    index += "$Port".length();
    if (str.charAt(index) != '=')
      return index;

    index++;
    if (str.charAt(index) != '\"')
      return startIndex;

    index++;
    newIndex = getLastPortList(str, index);
    if (index == newIndex)
      return startIndex;

    index = newIndex;
    if (str.charAt(index) != '\"')
      return startIndex;
    index++;
    return index;
  }

  /**
   * Method skipSpaces.
   * @param str
   * @param index
   * @return int
   */
  private int skipSpaces(String str, int index)
  {
    for (; index < str.length(); index++)
      if (!BasicRules.isSP(str.charAt(index)))
        break;
    return index;
  }

  /**
   * Method getValue.
   * @param str
   * @param beg
   * @param end
   * @return String
   */
  private String getValue(String str, int beg, int end)
  {
    String qqq = null;
    if (str.charAt(beg) == '\"')
      qqq = str.substring(beg + 1, end - 1);
    else
      qqq = str.substring(beg, end);
    return qqq;
  }

}
