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

import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.name.Names;
import java.io.File;
import java.util.Properties;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.mysql.conf.MySQLDriver;
import org.apache.guacamole.auth.mysql.conf.MySQLEnvironment;
import org.apache.guacamole.auth.mysql.conf.MySQLSSLMode;
import org.mybatis.guice.datasource.helper.JdbcHelper;

/**
 * Guice module which configures MySQL-specific injections.
 */
public class MySQLAuthenticationProviderModule implements Module {

    /**
     * MyBatis-specific configuration properties.
     */
    private final Properties myBatisProperties = new Properties();

    /**
     * MySQL-specific driver configuration properties.
     */
    private final Properties driverProperties = new Properties();
    
    /**
     * The MySQL-compatible driver that should be used to talk to the database
     * server.
     */
    private MySQLDriver mysqlDriver;
    
    /**
     * Creates a new MySQL authentication provider module that configures
     * driver and MyBatis properties using the given environment.
     *
     * @param environment
     *     The environment to use when configuring MyBatis and the underlying
     *     JDBC driver.
     *
     * @throws GuacamoleException
     *     If a required property is missing, or an error occurs while parsing
     *     a property.
     */
    public MySQLAuthenticationProviderModule(MySQLEnvironment environment)
            throws GuacamoleException {

        // Set the MySQL-specific properties for MyBatis.
        myBatisProperties.setProperty("mybatis.environment.id", "guacamole");
        myBatisProperties.setProperty("JDBC.host", environment.getMySQLHostname());
        myBatisProperties.setProperty("JDBC.port", String.valueOf(environment.getMySQLPort()));
        myBatisProperties.setProperty("JDBC.schema", environment.getMySQLDatabase());
        myBatisProperties.setProperty("JDBC.username", environment.getMySQLUsername());
        myBatisProperties.setProperty("JDBC.password", environment.getMySQLPassword());
        myBatisProperties.setProperty("JDBC.autoCommit", "false");
        myBatisProperties.setProperty("mybatis.pooled.pingEnabled", "true");
        myBatisProperties.setProperty("mybatis.pooled.pingQuery", "SELECT 1");

        // Use UTF-8 in database
        driverProperties.setProperty("characterEncoding", "UTF-8");

        // Allow use of multiple statements within a single query
        driverProperties.setProperty("allowMultiQueries", "true");
        
        // Set the SSL mode to use when conncting
        MySQLSSLMode sslMode = environment.getMySQLSSLMode();
        driverProperties.setProperty("sslMode", sslMode.getDriverValue());
        
        // For compatibility, set legacy useSSL property when SSL is disabled.
        if (sslMode == MySQLSSLMode.DISABLED)
            driverProperties.setProperty("useSSL", "false");
        
        // Check other SSL settings and set as required
        File trustStore = environment.getMySQLSSLTrustStore();
        if (trustStore != null)
            driverProperties.setProperty("trustCertificateKeyStoreUrl",
                    trustStore.getAbsolutePath());
        
        String trustPassword = environment.getMySQLSSLTrustPassword();
        if (trustPassword != null)
            driverProperties.setProperty("trustCertificateKeyStorePassword",
                    trustPassword);
        
        File clientStore = environment.getMySQLSSLClientStore();
        if (clientStore != null)
            driverProperties.setProperty("clientCertificateKeyStoreUrl",
                    clientStore.getAbsolutePath());
        
        String clientPassword = environment.getMYSQLSSLClientPassword();
        if (clientPassword != null)
            driverProperties.setProperty("clientCertificateKeyStorePassword",
                    clientPassword);
        
        // Get the MySQL-compatible driver to use.
        mysqlDriver = environment.getMySQLDriver();

    }

    @Override
    public void configure(Binder binder) {

        // Check which MySQL-compatible driver is in use
        switch(mysqlDriver) {
            
            // Bind MySQL-specific properties
            case MYSQL:
                JdbcHelper.MySQL.configure(binder);
                break;
                
            // Bind MariaDB-specific properties
            case MARIADB:
                JdbcHelper.MariaDB.configure(binder);
                break;
                
            default:
                throw new UnsupportedOperationException(
                    "A driver has been specified that is not supported by this module."
                );
        }

        // Bind MyBatis properties
        Names.bindProperties(binder, myBatisProperties);

        // Bind JDBC driver properties
        binder.bind(Properties.class)
            .annotatedWith(Names.named("JDBC.driverProperties"))
            .toInstance(driverProperties);

    }

}
