/*
  Copyright (C) 2006 Helge Hess

  This file is part of JOPE.

  JOPE is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the
  Free Software Foundation; either version 2, or (at your option) any
  later version.

  JOPE is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with JOPE; see the file COPYING.  If not, write to the
  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.
*/

package org.opengroupware.jope.appserver.core;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.opengroupware.jope.foundation.NSObject;

// TODO: complete class
public class WOCookie extends NSObject {
  protected static final Log log = LogFactory.getLog("WOCookie");
  
  protected String  name;
  protected String  value;
  protected String  path;
  protected String  domain;
  protected double  date     = 0.0;
  protected boolean isSecure = false;

  public WOCookie(String _name, String _value, String _path, String _domain, 
                  double _date, boolean _isSecure)
  {
    this.name     = _name;
    this.value    = _value;
    this.path     = _path;
    this.domain   = _domain;
    this.date     = _date;
    this.isSecure = _isSecure;
  }

  public WOCookie(String _name, String _value, String _path, String _domain, 
                  boolean _isSecure)
  {
    this.name     = _name;
    this.value    = _value;
    this.path     = _path;
    this.domain   = _domain;
    this.isSecure = _isSecure;
  }
  
  public WOCookie(String _name, String _value) {
    this.name  = _name;
    this.value = _value;
  }
  
  /* accessors */
  
  public void setName(String _s) {
    this.name = _s;
  }
  public String name() {
    return this.name;
  }
  
  public void setValue(String _s) {
    this.value = _s;
  }
  public String value() {
    return this.value;
  }

  public String headerString() {
    StringBuffer sb = new StringBuffer(256);
    
    // TODO: do we need to escape the value?
    sb.append(this.name());
    sb.append("=");
    sb.append(this.value());
    sb.append("; version=\"1\"");
    
    // TODO: max-age (timeout)
    // TODO: expires (date)
    
    if (this.path != null) {
      sb.append("; path=");
      sb.append(this.path);
    }
    if (this.domain != null) {
      sb.append("; domain=");
      sb.append(this.domain);
    }
    
    if (this.isSecure)
      sb.append("; secure");
    
    return sb.toString();
  }
  
  /* parsing cookies */
  
  public static WOCookie parseCookieString(String _s) {
    if (_s == null) return null;

    int idx = _s.indexOf('=');
    if (idx == -1) {
      log.warn("got invalid cookie value: '" + _s + "'");
      return null;
    }
    
    String name  = _s.substring(0, idx);
    String value = _s.substring(idx + 1);
    
    // TODO: process escaping
    
    idx = _s.indexOf(';');
    if (idx == -1)
      return new WOCookie(name, value);

    /* process options */
    
    String[] opts = value.substring(idx + 1).split(";");
    value = value.substring(0, idx);
    
    String  path = null, domain = null;
    boolean isSecure = false;
    
    for (int i = 0; i < opts.length; i++) {
      String opt = opts[i].trim();
      if (opt.startsWith("domain="))
        name = opt.substring(7);
      else if (opt.startsWith("path="))
        path = opt.substring(5);
      else if (opt.equals("secure"))
        isSecure = true;
      else
        log.error("unknown cookie option: " + opt + " in: " + _s);
    }
    
    return new WOCookie(name, value, path, domain, isSecure);
  }

  /* description */
  
  public void appendAttributesToDescription(StringBuffer _d) {
    if (this.name != null)
      _d.append(" name=" + this.name);
    if (this.value != null)
      _d.append(" value=" + this.value);
    
    if (this.path != null)
      _d.append(" path=" + this.path);
    if (this.domain != null)
      _d.append(" domain=" + this.domain);
    
    if (this.isSecure)
      _d.append(" secure");
  }
}
