/*
 * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.smartcardio;

import java.io.*;

import java.security.Permission;

/**
 * A permission for Smart Card operations. A CardPermission consists of the
 * name of the card terminal the permission applies to and a set of actions
 * that are valid for that terminal.
 *
 * <p>A CardPermission with a name of <code>*</code> applies to all
 * card terminals. The actions string is a comma separated list of the actions
 * listed below, or <code>*</code> to signify "all actions."
 *
 * <p>Individual actions are:
 * <dl>
 * <dt>connect
 * <dd>connect to a card using
 * {@linkplain CardTerminal#connect CardTerminal.connect()}
 *
 * <dt>reset
 * <dd>reset the card using {@linkplain Card#disconnect Card.disconnect(true)}
 *
 * <dt>exclusive
 * <dd>establish exclusive access to a card using
 * {@linkplain Card#beginExclusive} and {@linkplain Card#endExclusive
 * endExclusive()}
 *
 * <dt>transmitControl
 * <dd>transmit a control command using
 * {@linkplain Card#transmitControlCommand Card.transmitControlCommand()}
 *
 * <dt>getBasicChannel
 * <dd>obtain the basic logical channel using
 * {@linkplain Card#getBasicChannel}
 *
 * <dt>openLogicalChannel
 * <dd>open a new logical channel using
 * {@linkplain Card#openLogicalChannel}
 *
 * </dl>
 *
 * @since   1.6
 * @author  Andreas Sterbenz
 * @author  JSR 268 Expert Group
 */
public class CardPermission extends Permission {

    private static final long serialVersionUID = 7146787880530705613L;

    private final static int A_CONNECT              = 0x01;
    private final static int A_EXCLUSIVE            = 0x02;
    private final static int A_GET_BASIC_CHANNEL    = 0x04;
    private final static int A_OPEN_LOGICAL_CHANNEL = 0x08;
    private final static int A_RESET                = 0x10;
    private final static int A_TRANSMIT_CONTROL     = 0x20;

    // sum of all the actions above
    private final static int A_ALL                  = 0x3f;

    private final static int[] ARRAY_MASKS = {
        A_ALL,
        A_CONNECT,
        A_EXCLUSIVE,
        A_GET_BASIC_CHANNEL,
        A_OPEN_LOGICAL_CHANNEL,
        A_RESET,
        A_TRANSMIT_CONTROL,
    };

    private final static String S_CONNECT              = "connect";
    private final static String S_EXCLUSIVE            = "exclusive";
    private final static String S_GET_BASIC_CHANNEL    = "getBasicChannel";
    private final static String S_OPEN_LOGICAL_CHANNEL = "openLogicalChannel";
    private final static String S_RESET                = "reset";
    private final static String S_TRANSMIT_CONTROL     = "transmitControl";

    private final static String S_ALL                  = "*";

    private final static String[] ARRAY_STRINGS = {
        S_ALL,
        S_CONNECT,
        S_EXCLUSIVE,
        S_GET_BASIC_CHANNEL,
        S_OPEN_LOGICAL_CHANNEL,
        S_RESET,
        S_TRANSMIT_CONTROL,
    };

    private transient int mask;

    /**
     * @serial
     */
    private volatile String actions;

    /**
     * Constructs a new CardPermission with the specified actions.
     * <code>terminalName</code> is the name of a CardTerminal or <code>*</code>
     * if this permission applies to all terminals. <code>actions</code>
     * contains a comma-separated list of the individual actions
     * or <code>*</code> to signify all actions. For more information,
     * see the documentation at the top of this {@linkplain CardPermission
     * class}.
     *
     * @param terminalName the name of the card terminal, or <code>*</code>
     * @param actions the action string (or null if the set of permitted
     *   actions is empty)
     *
     * @throws NullPointerException if terminalName is null
     * @throws IllegalArgumentException if actions is an invalid actions
     *   specification
     */
    public CardPermission(String terminalName, String actions) {
        super(terminalName);
        if (terminalName == null) {
            throw new NullPointerException();
        }
        mask = getMask(actions);
    }

    private static int getMask(String actions) {
        if ((actions == null) || (actions.length() == 0)) {
            throw new IllegalArgumentException("actions must not be empty");
        }

        // try exact matches for simple actions first
        for (int i = 0; i < ARRAY_STRINGS.length; i++) {
            if (actions == ARRAY_STRINGS[i]) {
                return ARRAY_MASKS[i];
            }
        }

        if (actions.endsWith(",")) {
            throw new IllegalArgumentException("Invalid actions: '" + actions + "'");
        }
        int mask = 0;
        String[] split = actions.split(",");
    outer:
        for (String s : split) {
            for (int i = 0; i < ARRAY_STRINGS.length; i++) {
                if (ARRAY_STRINGS[i].equalsIgnoreCase(s)) {
                    mask |= ARRAY_MASKS[i];
                    continue outer;
                }
            }
            throw new IllegalArgumentException("Invalid action: '" + s + "'");
        }

        return mask;
    }

    private static String getActions(int mask) {
        if (mask == A_ALL) {
            return S_ALL;
        }
        boolean first = true;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < ARRAY_MASKS.length; i++) {
            int action = ARRAY_MASKS[i];
            if ((mask & action) == action) {
                if (first == false) {
                    sb.append(",");
                } else {
                    first = false;
                }
                sb.append(ARRAY_STRINGS[i]);
            }
        }
        return sb.toString();
    }


    /**
     * Returns the canonical string representation of the actions.
     * It is <code>*</code> to signify all actions defined by this class or
     * the string concatenation of the comma-separated,
     * lexicographically sorted list of individual actions.
     *
     * @return the canonical string representation of the actions.
     */
    public String getActions() {
        if (actions == null) {
            actions = getActions(mask);
        }
        return actions;
    }

    /**
     * Checks if this CardPermission object implies the specified permission.
     * That is the case, if and only if
     * <ul>
     * <li><p><code>permission</code> is an instance of CardPermission,</p>
     * <li><p><code>permission</code>'s actions are a proper subset of this
     *   object's actions, and</p>
     * <li><p>this object's <code>getName()</code> method is either
     *   <code>*</code> or equal to <code>permission</code>'s <code>name</code>.
     *   </p>
     * </ul>
     *
     * @param permission the permission to check against
     * @return true if and only if this CardPermission object implies the
     *   specified permission.
     */
    public boolean implies(Permission permission) {
        if (permission instanceof CardPermission == false) {
            return false;
        }
        CardPermission other = (CardPermission)permission;
        if ((this.mask & other.mask) != other.mask) {
            return false;
        }
        String thisName = getName();
        if (thisName.equals("*")) {
            return true;
        }
        if (thisName.equals(other.getName())) {
            return true;
        }
        return false;
    }

    /**
     * Compares the specified object with this CardPermission for equality.
     * This CardPermission is equal to another Object <code>object</code>, if
     * and only if
     * <ul>
     * <li><p><code>object</code> is an instance of CardPermission,</p>
     * <li><p><code>this.getName()</code> is equal to
     * <code>((CardPermission)object).getName()</code>, and</p>
     * <li><p><code>this.getActions()</code> is equal to
     * <code>((CardPermission)object).getActions()</code>.</p>
     * </ul>
     *
     * @param obj the object to be compared for equality with this CardPermission
     * @return true if and only if the specified object is equal to this
     *   CardPermission
     */
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof CardPermission == false) {
            return false;
        }
        CardPermission other = (CardPermission)obj;
        return this.getName().equals(other.getName()) && (this.mask == other.mask);
    }

    /**
     * Returns the hash code value for this CardPermission object.
     *
     * @return the hash code value for this CardPermission object.
     */
    public int hashCode() {
        return getName().hashCode() + 31 * mask;
    }

    private void writeObject(ObjectOutputStream s) throws IOException {
        // Write out the actions. The superclass takes care of the name.
        // Call getActions to make sure actions field is initialized
        if (actions == null) {
            getActions();
        }
        s.defaultWriteObject();
    }

    private void readObject(ObjectInputStream s)
            throws IOException, ClassNotFoundException {
        // Read in the actions, then restore the mask.
        s.defaultReadObject();
        mask = getMask(actions);
    }

}
