/**
 * Copyright (c) 2010-2012 EBM WebSourcing, 2012-2013 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library 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 Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see <http://www.gnu.org/licenses/>
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.cli.connection;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import java.util.HashMap;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.junit.BeforeClass;
import org.junit.Test;
import org.ow2.petals.cli.api.command.exception.CommandBadArgumentNumberException;
import org.ow2.petals.cli.api.command.exception.CommandException;
import org.ow2.petals.cli.api.connection.AuthenticatedConnectionParameters;
import org.ow2.petals.cli.api.connection.ConnectionParameters;

public class ConnectionHelperTest {
    
    private final static Options OPTIONS = new Options();

    private final static String CONFIRMATION_SHORT_OPTION = "y";
    
    static {
        ConnectionHelper.addConnectionOptions(ConnectionHelperTest.OPTIONS);
        ConnectionHelperTest.OPTIONS.addOption(OptionBuilder.hasArg(false).create(CONFIRMATION_SHORT_OPTION));
    }
    
    private static HashMap<String, ConnectionParameters> preferenceConnectionParameters;
    private static ConnectionParameters connectionParameters1;
    private static ConnectionParameters defaultConnectionParameters;
    private static ConnectionParameters connectionParameters3;
    
    @BeforeClass
    public static void beforeClass() {
        preferenceConnectionParameters = new HashMap<String, ConnectionParameters>();
        connectionParameters1 = new ConnectionParameters("testHost1", 7845);
        preferenceConnectionParameters.put("aliasTest1", connectionParameters1);
        defaultConnectionParameters = new ConnectionParameters("testHost2", 4875);
        preferenceConnectionParameters.put("aliasTest2", defaultConnectionParameters);
        connectionParameters3 = new AuthenticatedConnectionParameters("testHost3", 4123,
                "testUser", "testPassword", null);
        preferenceConnectionParameters.put("aliasTest3", connectionParameters3);
    }
    
    @Test
    public final void testParseConnectionParametersWithNothingAndUseDefault() throws Exception {
        final CommandLineParser parser = new PosixParser();
        String args = "connect";
        final CommandLine cmd = parser.parse(ConnectionHelperTest.OPTIONS, args.split(" "));

        ConnectionParameters connectionParameters = ConnectionHelper.parseConnectionParameters(cmd,
                true, preferenceConnectionParameters, defaultConnectionParameters);
        assertEquals(defaultConnectionParameters, connectionParameters);
    }
    
    @Test
    public final void testParseConnectionParametersWithNothingNotUseDefault() throws Exception {
        final CommandLineParser parser = new PosixParser();
        String args = "connect";
        final CommandLine cmd = parser.parse(ConnectionHelperTest.OPTIONS, args.split(" "));

        ConnectionParameters connectionParameters = ConnectionHelper.parseConnectionParameters(cmd,
                false, preferenceConnectionParameters, defaultConnectionParameters);
        assertNull(connectionParameters);
    }
    
    @Test
    public final void testParseConnectionParametersWithAlias() throws Exception {
        final CommandLineParser parser = new PosixParser();
        String args = "connect -a aliasTest3";
        final CommandLine cmd = parser.parse(ConnectionHelperTest.OPTIONS, args.split(" "));

        ConnectionParameters connectionParameters = ConnectionHelper.parseConnectionParameters(cmd,
                true, preferenceConnectionParameters, defaultConnectionParameters);
        assertEquals(connectionParameters3, connectionParameters);
    }
    
    @Test
    public final void testParseConnectionParametersWithParameters() throws Exception {
        final CommandLineParser parser = new PosixParser();
        String args = "connect -h localhost -n 7700 -u testUser -p testPwd";
        final CommandLine cmd = parser.parse(ConnectionHelperTest.OPTIONS, args.split(" "));

        ConnectionParameters connectionParameters = ConnectionHelper.parseConnectionParameters(cmd,
                true, preferenceConnectionParameters, defaultConnectionParameters);
        assertEquals(new AuthenticatedConnectionParameters("localhost", 7700, "testUser",
                "testPwd", null), connectionParameters);
    }
    
    @Test(expected =  CommandException.class)
    public final void testParseConnectionParametersWithIncompatibleArguments() throws Exception {
        final CommandLineParser parser = new PosixParser();
        String args = "connect -h localhost -n 7700 -u testUser -p testPwd -a aliasTest1";
        final CommandLine cmd = parser.parse(ConnectionHelperTest.OPTIONS, args.split(" "));

        try {
        ConnectionHelper.parseConnectionParameters(cmd,
                true, preferenceConnectionParameters, defaultConnectionParameters);
        } catch(CommandException ce) {
            assertEquals(
                    CommandBadArgumentNumberException.BAD_NUMBER_OF_ARGUMENTS_OR_INCOMPATIBLE_ARGUMENTS,
                    ce.getMessage());
            throw ce;
        }
    }
    
    @Test(expected =  CommandException.class)
    public final void testParseConnectionParametersWithBadNumberOfArguments() throws Exception {
        final CommandLineParser parser = new PosixParser();
        String args = "connect -h localhost -n 7700";
        final CommandLine cmd = parser.parse(ConnectionHelperTest.OPTIONS, args.split(" "));

        try {
        ConnectionHelper.parseConnectionParameters(cmd,
                true, preferenceConnectionParameters, defaultConnectionParameters);
        } catch(CommandException ce) {
            assertEquals(
                    CommandBadArgumentNumberException.BAD_NUMBER_OF_ARGUMENTS_OR_INCOMPATIBLE_ARGUMENTS,
                    ce.getMessage());
            throw ce;
        }
    }
}
