/*
 * 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.guacamole.token;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.Credentials;

/**
 * Utility class which provides access to standardized token names, as well as
 * facilities for generating those tokens from common objects.
 */
public class StandardTokens {

    /**
     * The name of the username token added via addStandardTokens().
     */
    public static final String USERNAME_TOKEN = "GUAC_USERNAME";

    /**
     * The name of the password token added via addStandardTokens().
     */
    public static final String PASSWORD_TOKEN = "GUAC_PASSWORD";

    /**
     * The name of the client hostname token added via addStandardTokens().
     */
    public static final String CLIENT_HOSTNAME_TOKEN = "GUAC_CLIENT_HOSTNAME";

    /**
     * The name of the client address token added via addStandardTokens().
     */
    public static final String CLIENT_ADDRESS_TOKEN = "GUAC_CLIENT_ADDRESS";

    /**
     * The name of the date token (server-local time) added via
     * addStandardTokens().
     */
    public static final String DATE_TOKEN = "GUAC_DATE";

    /**
     * The name of the time token (server-local time) added via
     * addStandardTokens().
     */
    public static final String TIME_TOKEN = "GUAC_TIME";

    /**
     * The date format that should be used for the date token. This format must
     * be compatible with Java's SimpleDateFormat.
     */
    private static final String DATE_FORMAT = "yyyyMMdd";

    /**
     * The date format that should be used for the time token. This format must
     * be compatible with Java's SimpleDateFormat.
     */
    private static final String TIME_FORMAT = "HHmmss";

    /**
     * The prefix of the arbitrary attribute tokens.
     */
    public static final String ATTR_TOKEN_PREFIX = "GUAC_ATTR_";

    /**
     * This utility class should not be instantiated.
     */
    private StandardTokens() {}

    /**
     * Adds tokens which are standardized by guacamole-ext to the given
     * TokenFilter and which do not require a corresponding Credentials object.
     * These the server date and time (GUAC_DATE and GUAC_TIME respectively).
     *
     * @param filter
     *     The TokenFilter to add standard tokens to.
     */
    public static void addStandardTokens(TokenFilter filter) {

        // Add date/time tokens (server-local time)
        Date currentTime = new Date();
        filter.setToken(DATE_TOKEN, new SimpleDateFormat(DATE_FORMAT).format(currentTime));
        filter.setToken(TIME_TOKEN, new SimpleDateFormat(TIME_FORMAT).format(currentTime));

    }

    /**
     * Adds tokens which are standardized by guacamole-ext to the given
     * TokenFilter using the values from the given Credentials object. These
     * standardized tokens include the current username (GUAC_USERNAME),
     * password (GUAC_PASSWORD), and the server date and time (GUAC_DATE and
     * GUAC_TIME respectively). If either the username or password are not set
     * within the given credentials, the corresponding token(s) will remain
     * unset.
     *
     * @param filter
     *     The TokenFilter to add standard tokens to.
     *
     * @param credentials
     *     The Credentials to use when populating the GUAC_USERNAME and
     *     GUAC_PASSWORD tokens.
     */
    public static void addStandardTokens(TokenFilter filter, Credentials credentials) {

        // Add username token
        String username = credentials.getUsername();
        if (username != null)
            filter.setToken(USERNAME_TOKEN, username);

        // Add password token
        String password = credentials.getPassword();
        if (password != null)
            filter.setToken(PASSWORD_TOKEN, password);

        // Add client hostname token
        String hostname = credentials.getRemoteHostname();
        if (hostname != null)
            filter.setToken(CLIENT_HOSTNAME_TOKEN, hostname);

        // Add client address token
        String address = credentials.getRemoteAddress();
        if (address != null)
            filter.setToken(CLIENT_ADDRESS_TOKEN, address);

        // Add any tokens which do not require credentials
        addStandardTokens(filter);

    }

    /**
     * Adds tokens which are standardized by guacamole-ext to the given
     * TokenFilter using the values from the given AuthenticatedUser object,
     * including any associated credentials. These standardized tokens include
     * the current username (GUAC_USERNAME), password (GUAC_PASSWORD), the
     * server date and time (GUAC_DATE and GUAC_TIME respectively), and custom
     * user attributes. If either the username or password are not set within
     * the given user or their provided credentials, the corresponding token(s)
     * will remain unset.
     *
     * @param filter
     *     The TokenFilter to add standard tokens to.
     *
     * @param user
     *     The AuthenticatedUser to use when populating the GUAC_USERNAME and
     *     GUAC_PASSWORD tokens.
     */
    public static void addStandardTokens(TokenFilter filter, AuthenticatedUser user) {

        // Default to the authenticated user's username for the GUAC_USERNAME
        // token
        filter.setToken(USERNAME_TOKEN, user.getIdentifier());

        // Add tokens specific to credentials
        addStandardTokens(filter, user.getCredentials());

        // Add custom attribute tokens
        addAttributeTokens(filter, user.getAttributes());
    }

    /**
     * Add attribute tokens to StandardTokens.  These are arbitrary
     * key/value pairs that may be configured by the various authentication
     * extensions.
     *
     * @param filter
     *     The TokenFilter to add attribute tokens to.
     *
     * @param attributes
     *     The map of key/value pairs to add tokens for.
     */
    public static void addAttributeTokens(TokenFilter filter,
            Map<String, String> attributes) {

        if (attributes != null) {
            for (Map.Entry entry : attributes.entrySet()) {
                String key = entry.getKey().toString();
                String tokenName = ATTR_TOKEN_PREFIX + key.toUpperCase();
                String tokenValue = entry.getValue().toString();
                filter.setToken(tokenName, tokenValue);
            }
        }

    }

}
