/*
 * 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.auth.postgresql.conf;

import java.io.File;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.jdbc.JDBCEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.guacamole.auth.jdbc.security.PasswordPolicy;
import org.apache.ibatis.session.SqlSession;

/**
 * A PostgreSQL-specific implementation of JDBCEnvironment provides database
 * properties specifically for PostgreSQL.
 */
public class PostgreSQLEnvironment extends JDBCEnvironment {

    /**
     * Logger for this class.
     */
    private static final Logger logger = LoggerFactory.getLogger(PostgreSQLEnvironment.class);

    /**
     * The default host to connect to, if POSTGRESQL_HOSTNAME is not specified.
     */
    private static final String DEFAULT_HOSTNAME = "localhost";

    /**
     * The default port to connect to, if POSTGRESQL_PORT is not specified.
     */
    private static final int DEFAULT_PORT = 5432;

    /**
     * The default number of seconds the driver will wait for a response from
     * the database, before aborting the query.
     * A value of 0 (the default) means the timeout is disabled.
     */
    private static final int DEFAULT_STATEMENT_TIMEOUT = 0;

    /**
     * The default number of seconds to wait for socket read operations.
     * A value of 0 (the default) means the timeout is disabled.
     */
    private static final int DEFAULT_SOCKET_TIMEOUT = 0;

    /**
     * Whether a database user account is required by default for authentication
     * to succeed.
     */
    private static final boolean DEFAULT_USER_REQUIRED = false;

    /**
     * The default value for the maximum number of connections to be
     * allowed to the Guacamole server overall.
     */
    private final int DEFAULT_ABSOLUTE_MAX_CONNECTIONS = 0;

    /**
     * The default value for the default maximum number of connections to be
     * allowed per user to any one connection. Note that, as long as the
     * legacy "disallow duplicate" and "disallow simultaneous" properties are
     * still supported, these cannot be constants, as the legacy properties
     * dictate the values that should be used in the absence of the correct
     * properties.
     */
    private final int DEFAULT_MAX_CONNECTIONS_PER_USER = 1;

    /**
     * The default value for the default maximum number of connections to be
     * allowed per user to any one connection group. Note that, as long as the
     * legacy "disallow duplicate" and "disallow simultaneous" properties are
     * still supported, these cannot be constants, as the legacy properties
     * dictate the values that should be used in the absence of the correct
     * properties.
     */
    private final int DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER = 1;

    /**
     * The default value for the default maximum number of connections to be
     * allowed to any one connection. Note that, as long as the legacy
     * "disallow duplicate" and "disallow simultaneous" properties are still
     * supported, these cannot be constants, as the legacy properties dictate
     * the values that should be used in the absence of the correct properties.
     */
    private final int DEFAULT_MAX_CONNECTIONS = 0;

    /**
     * The default value for the default maximum number of connections to be
     * allowed to any one connection group. Note that, as long as the legacy
     * "disallow duplicate" and "disallow simultaneous" properties are still
     * supported, these cannot be constants, as the legacy properties dictate
     * the values that should be used in the absence of the correct properties.
     */
    private final int DEFAULT_MAX_GROUP_CONNECTIONS = 0;
    
    /**
     * The default value to use for SSL mode if none is explicitly configured.
     */
    private final PostgreSQLSSLMode DEFAULT_SSL_MODE = PostgreSQLSSLMode.PREFER;

    /**
     * Constructs a new PostgreSQLEnvironment, providing access to PostgreSQL-specific
     * configuration options.
     * 
     * @throws GuacamoleException 
     *     If an error occurs while setting up the underlying JDBCEnvironment
     *     or while parsing legacy PostgreSQL configuration options.
     */
    public PostgreSQLEnvironment() throws GuacamoleException {

        // Init underlying JDBC environment
        super();

    }

    @Override
    public boolean isUserRequired() throws GuacamoleException {
        return getProperty(
            PostgreSQLGuacamoleProperties.POSTGRESQL_USER_REQUIRED,
            DEFAULT_USER_REQUIRED
        );
    }

    @Override
    public int getAbsoluteMaxConnections() throws GuacamoleException {
        return getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_ABSOLUTE_MAX_CONNECTIONS,
            DEFAULT_ABSOLUTE_MAX_CONNECTIONS
        );
    }

    @Override
    public int getDefaultMaxConnections() throws GuacamoleException {
        return getProperty(
            PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS,
            DEFAULT_MAX_CONNECTIONS
        );
    }

    @Override
    public int getDefaultMaxGroupConnections() throws GuacamoleException {
        return getProperty(
            PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS,
            DEFAULT_MAX_GROUP_CONNECTIONS
        );
    }

    @Override
    public int getDefaultMaxConnectionsPerUser() throws GuacamoleException {
        return getProperty(
            PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS_PER_USER,
            DEFAULT_MAX_CONNECTIONS_PER_USER
        );
    }

    @Override
    public int getDefaultMaxGroupConnectionsPerUser() throws GuacamoleException {
        return getProperty(
            PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER,
            DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER
        );
    }

    @Override
    public PasswordPolicy getPasswordPolicy() {
        return new PostgreSQLPasswordPolicy(this);
    }

    /**
     * Returns the hostname of the PostgreSQL server hosting the Guacamole
     * authentication tables. If unspecified, this will be "localhost".
     * 
     * @return
     *     The URL of the PostgreSQL server.
     *
     * @throws GuacamoleException 
     *     If an error occurs while retrieving the property value.
     */
    public String getPostgreSQLHostname() throws GuacamoleException {
        return getProperty(
            PostgreSQLGuacamoleProperties.POSTGRESQL_HOSTNAME,
            DEFAULT_HOSTNAME
        );
    }
    
    /**
     * Returns the port number of the PostgreSQL server hosting the Guacamole
     * authentication tables. If unspecified, this will be the default
     * PostgreSQL port of 5432.
     * 
     * @return
     *     The port number of the PostgreSQL server.
     *
     * @throws GuacamoleException 
     *     If an error occurs while retrieving the property value.
     */
    public int getPostgreSQLPort() throws GuacamoleException {
        return getProperty(
            PostgreSQLGuacamoleProperties.POSTGRESQL_PORT,
            DEFAULT_PORT
        );
    }
    
    /**
     * Returns the name of the PostgreSQL database containing the Guacamole
     * authentication tables.
     * 
     * @return
     *     The name of the PostgreSQL database.
     *
     * @throws GuacamoleException 
     *     If an error occurs while retrieving the property value, or if the
     *     value was not set, as this property is required.
     */
    public String getPostgreSQLDatabase() throws GuacamoleException {
        return getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_DATABASE);
    }
    
    /**
     * Returns the username that should be used when authenticating with the
     * PostgreSQL database containing the Guacamole authentication tables.
     * 
     * @return
     *     The username for the PostgreSQL database.
     *
     * @throws GuacamoleException 
     *     If an error occurs while retrieving the property value, or if the
     *     value was not set, as this property is required.
     */
    public String getPostgreSQLUsername() throws GuacamoleException {
        return getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_USERNAME);
    }
    
    /**
     * Returns the password that should be used when authenticating with the
     * PostgreSQL database containing the Guacamole authentication tables.
     * 
     * @return
     *     The password for the PostgreSQL database.
     *
     * @throws GuacamoleException 
     *     If an error occurs while retrieving the property value, or if the
     *     value was not set, as this property is required.
     */
    public String getPostgreSQLPassword() throws GuacamoleException {
        return getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_PASSWORD);
    }
    
    /**
     * Returns the defaultStatementTimeout set for PostgreSQL connections.
     * If unspecified, this will default to 0,
     * and should not be passed through to the backend.
     * 
     * @return
     *     The statement timeout (in seconds)
     *
     * @throws GuacamoleException 
     *     If an error occurs while retrieving the property value.
     */
    public int getPostgreSQLDefaultStatementTimeout() throws GuacamoleException {
        return getProperty(
            PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_STATEMENT_TIMEOUT,
            DEFAULT_STATEMENT_TIMEOUT
        );
    }
    
    /**
     * Returns the socketTimeout property to set on PostgreSQL connections.
     * If unspecified, this will default to 0 (no timeout)
     * 
     * @return
     *     The socketTimeout to use when waiting on read operations (in seconds)
     *
     * @throws GuacamoleException 
     *     If an error occurs while retrieving the property value.
     */
    public int getPostgreSQLSocketTimeout() throws GuacamoleException {
        return getProperty(
            PostgreSQLGuacamoleProperties.POSTGRESQL_SOCKET_TIMEOUT,
            DEFAULT_SOCKET_TIMEOUT
        );
    }

    @Override
    public boolean isRecursiveQuerySupported(SqlSession session) {
        return true; // All versions of PostgreSQL support recursive queries through CTEs
    }
    
    /**
     * Get the SSL mode to use to make the JDBC connection to the PostgreSQL
     * server.  If unspecified this will default to PREFER, attempting SSL
     * and falling back to plain-text if SSL fails.
     * 
     * @return
     *     The enum value of the SSL mode to use to make the JDBC connection
     *     to the server.
     * 
     * @throws GuacamoleException 
     *     If an error occurs retrieving the value from guacamole.properties.
     */
    public PostgreSQLSSLMode getPostgreSQLSSLMode() throws GuacamoleException {
        return getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_SSL_MODE,
                DEFAULT_SSL_MODE);
    }
    
    /**
     * Return the SSL client certificate file to use to make the connection
     * to the PostgreSQL server.
     * 
     * @return
     *     The SSL client certificate file to use for the PostgreSQL connection.
     * 
     * @throws GuacamoleException
     *     If an error occurs retrieving the value from guacamole.properties.
     */
    public File getPostgreSQLSSLClientCertFile() throws GuacamoleException {
        return getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_SSL_CERT_FILE);
    }
    
    /**
     * Return the SSL client private key file to use to make the connection to the
     * PostgreSQL server.
     * 
     * @return
     *     The SSL client private key file to use for the PostgreSQL connection.
     * @throws GuacamoleException 
     *     If an error occurs retrieving the value from guacamole.properties.
     */
    public File getPostgreSQLSSLClientKeyFile() throws GuacamoleException {
        return getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_SSL_KEY_FILE);
    }
    
    /**
     * Return the SSL client root certificate file to use to make the connection
     * to the PostgreSQL server.
     * 
     * @return
     *     The SSL client root certificate file to use to make the connection
     *     to the PostgreSQL server.
     * 
     * @throws GuacamoleException 
     *     If an error occurs retrieving the value from guacamole.properties.
     */
    public File getPostgreSQLSSLClientRootCertFile() throws GuacamoleException {
        return getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_SSL_ROOT_CERT_FILE);
    }
    
    /**
     * Return the password to use to decrypt the private SSL key file when making
     * the connection to the PostgreSQL server.
     * 
     * @return
     *     The password to use to decrypt the private SSL key file when making
     *     the connection to the PostgreSQL server.
     * 
     * @throws GuacamoleException 
     *     If an error occurs retrieving the value from guacamole.properties.
     */
    public String getPostgreSQLSSLClientKeyPassword() throws GuacamoleException {
        return getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_SSL_KEY_PASSWORD);
    }
    
    @Override
    public boolean autoCreateAbsentAccounts() throws GuacamoleException {
        return getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_AUTO_CREATE_ACCOUNTS,
                false);
    }
    
}
