//////////////////////////////////////////////////////////////////////////// 
// 
// Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1993, 1994, 1995.
// Unpublished work.  All Rights Reserved.
// 
// The software contained on this media is the property of the
// DSTC Pty Ltd.  Use of this software is strictly in accordance
// with the license agreement in the accompanying LICENSE.DOC 
// file. If your distribution of this software does not contain 
// a LICENSE.DOC file then you have no rights to use this 
// software in any manner and should contact DSTC at the address 
// below to determine an appropriate licensing arrangement.
// 
//      DSTC Pty Ltd
//      Level 7, GP South
//      University of Queensland
//      St Lucia, 4072
//      Australia
//      Tel: +61 7 3365 4310
//      Fax: +61 7 3365 4311
//      Email: jcsi@dstc.qut.edu.au
// 
// This software is being provided "AS IS" without warranty of
// any kind.  In no event shall DSTC Pty Ltd be liable for
// damage of any kind arising out of or in connection with
// the use or performance of this software.
// 
//////////////////////////////////////////////////////////////////////////// 

package com.dstc.security.kerberos.v5.base;

import java.util.StringTokenizer;

import com.dstc.security.asn1.Asn1Exception;
import com.dstc.security.asn1.BitString;

/**
 * <p>A class representing the Kerberos ASN.1 structure TicketFlags.
 *
 * <pre>
 * TicketFlags :== BIT STRING {
 *                  reserved(0),
 *                  forwardable(1),
 *                  forwarded(2),
 *                  proxiable(3),
 *                  proxy(4),
 *                  may-postdate(5),
 *                  postdated(6),
 *                  invalid(7),
 *                  renewable(8),
 *                  initial(9),
 *                  pre-authent(10),
 *                  hw-authent(11),
 *                  transited-policy-checked(12),
 *                  ok-as-delegate(13)
 *                  anonymous(14)
 * }
 * </pre>
 *
 * @version 0.98, 98/07/01
 * @author Ming Yung
 */
public final class TicketFlags extends BitString
{
  /**
   * Constructs a TicketFlags. A boolean value of 'true' passed means that the
   * corresponding flag will be turned on.
   */
  public TicketFlags(boolean forwardable, boolean forwarded, boolean proxiable,
     boolean proxy, boolean may_postdate, boolean postdated,
     boolean invalid, boolean renewable, boolean initial,
     boolean pre_authent, boolean hw_authent,
     boolean transited_policy_checked, boolean ok_as_delegate,
     boolean anonymous) {
    super();

    contents = new byte[5];
    contents[0] = (byte) 0x00;   // number of padded bits
    contents[1] = (byte) 0x00;
    contents[2] = (byte) 0x00;
    contents[3] = (byte) 0x00;
    contents[4] = (byte) 0x00;
    
    if (forwardable)
      contents[1] |= (byte) 0x40;
    if (forwarded)
      contents[1] |= (byte) 0x20;
    if (proxiable)
      contents[1] |= (byte) 0x10;
    if (proxy)
      contents[1] |= (byte) 0x08;
    if (may_postdate)
      contents[1] |= (byte) 0x04;
    if (postdated)
      contents[1] |= (byte) 0x02;
    if (invalid)
      contents[1] |= (byte) 0x01;
    if (renewable)
      contents[2] |= (byte) 0x80;
    if (initial)
      contents[2] |= (byte) 0x40;
    if (pre_authent)
      contents[2] |= (byte) 0x20;
    if (hw_authent)
      contents[2] |= (byte) 0x10;
    if (transited_policy_checked)
      contents[2] |= (byte) 0x08;
    if (ok_as_delegate)
      contents[2] |= (byte) 0x04;
    if (anonymous)
      contents[2] |= (byte) 0x02;
  }

  /**
   * Constructs a TicketFlags from a string containing flag names.
   * Those flags named will be turned on. The string could be the value of an
   * appropriate property. For example:
   *    <p> krb5.kdc.defaultflags=forwardable, renewable
   *
   * A string containing a list of flag names is a very convenient way of 
   * requesting those flags be turned on. Acceptable flag names are: 
   * forwardable, forwarded, proxiable, proxy, may-postdate, postdated, invalid,
   * renewable, initial, pre-authent, hw-authent, transited-policy-checked, 
   * ok-as-delegate, anonymous. Flag names are not case-sensitive.
   *
   * @param flags A string containing a list of comma separated flag names.
   */
  public TicketFlags(String flags) {
    super();

    contents = new byte[5];
    contents[0] = (byte) 0x00;   // number of padded bits
    contents[1] = (byte) 0x00;
    contents[2] = (byte) 0x00;
    contents[3] = (byte) 0x00;
    contents[4] = (byte) 0x00;

    StringTokenizer tknz = new StringTokenizer(flags, " \t\n\r\f,");

    String option;
    while (tknz.hasMoreTokens()) {
      option = tknz.nextToken().toUpperCase();
      if (option.equals("FORWARDABLE"))
        contents[1] |= (byte) 0x40;
      else if (option.equals("FORWARDED"))
        contents[1] |= (byte) 0x20;
      else if (option.equals("PROXIABLE"))
        contents[1] |= (byte) 0x10;
      else if (option.equals("PROXY"))
        contents[1] |= (byte) 0x08;
      else if (option.equals("MAY-POSTDATE"))
        contents[1] |= (byte) 0x04;
      else if (option.equals("POSTDATED"))
        contents[1] |= (byte) 0x02;
      else if (option.equals("INVALID"))
contents[1] |= (byte) 0x01;
      else if (option.equals("RENEWABLE"))
        contents[2] |= (byte) 0x80;
      else if (option.equals("INITIAL"))
        contents[2] |= (byte) 0x40;
      else if (option.equals("PRE-AUTHENT"))
        contents[2] |= (byte) 0x20;
      else if (option.equals("HW-AUTHENT"))
        contents[2] |= (byte) 0x10;
      else if (option.equals("TRANSITED-POLICY-CHECKED"))
        contents[2] |= (byte) 0x08;
      else if (option.equals("OK-AS-DELEGATE"))
        contents[2] |= (byte) 0x04;
      else if (option.equals("ANONYMOUS"))
        contents[2] |= (byte) 0x02;
    }
  }

  /**
   * Constructs a TicketFlags from a bit mask as an int
   */
  public TicketFlags(int flags) {
    super();

    contents = new byte[5];

    contents[0] = (byte)0x00;
    contents[1] = (byte)((flags >> 24) & 0xff);
    contents[2] = (byte)((flags >> 16) & 0xff);
    contents[3] = (byte)((flags >> 8) & 0xff);
    contents[4] = (byte)(flags & 0xff);
  }

  /**
   * Constructs a TicketFlags from a DER encoding
   */
  public TicketFlags(byte encoded[]) throws Asn1Exception
  {
    doDecode(encoded);
  }

  /**
   * Check if a flag is set.
   *
   * @see #TicketFlags
   * @param flag Name of the flag to check for.
   */
  public boolean isOn(String flag) {
    String option = flag.toUpperCase();

    if (option.equals("FORWARDABLE"))
      return (contents[1] & (byte) 0x40) != 0;
    else if (option.equals("FORWARDED"))
      return (contents[1] & (byte) 0x20) != 0;
    else if (option.equals("PROXIABLE"))
      return (contents[1] & (byte) 0x10) != 0;
    else if (option.equals("PROXY"))
      return (contents[1] & (byte) 0x08) != 0;
    else if (option.equals("MAY-POSTDATE"))
      return (contents[1] & (byte) 0x04) != 0;
    else if (option.equals("POSTDATED"))
      return (contents[1] & (byte) 0x02) != 0;
    else if (option.equals("INVALID"))
      return (contents[2] & (byte) 0x01) != 0;
    else if (option.equals("RENEWABLE"))
      return (contents[2] & (byte) 0x80) != 0;
    else if (option.equals("INITIAL"))
      return (contents[2] & (byte) 0x40) != 0;
    else if (option.equals("PRE-AUTHENT"))
      return (contents[2] & (byte) 0x20) != 0;
    else if (option.equals("HW-AUTHENT"))
      return (contents[2] & (byte) 0x10) != 0;
    else if (option.equals("TRANSITED-POLICY-CHECKED"))
      return (contents[2] & (byte) 0x08) != 0;
    else if (option.equals("OK-AS-DELEGATE"))
      return (contents[2] & (byte) 0x04) != 0;
    else if (option.equals("ANONYMOUS"))
      return (contents[2] & (byte) 0x02) != 0;

    return false;
  }

  /**
   * Get the flags bytes
   */
  public byte[] getFlags()
  {
    return getBytes();
  }

  /**
   * Get the flags as an int mask
   */
  public int getFlagsMask() {
    byte[] flags = getBytes();
    int retval = (((flags[0] & 0xff) << 24) | ((flags[1] & 0xff) << 16) | 
           ((flags[2] & 0xff) <<  8) | (flags[3] & 0xff));
    return retval;
  }
}
