/**
 * 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.jboss.installer.postinstall.task;

import org.jboss.installer.auto.InstallationDataSerializer;
import org.jboss.installer.core.InstallationData;
import org.jboss.installer.postinstall.TaskPrinter;
import org.jboss.installer.postinstall.server.DomainServer;
import org.jboss.installer.postinstall.server.StandaloneServer;
import org.jboss.installer.postinstall.task.secdom.DatabaseSecurity;
import org.jboss.installer.test.utils.MockLanguageUtils;
import org.jboss.installer.test.utils.TestServer;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.nio.file.Path;
import java.util.Optional;

import static org.jboss.installer.test.utils.TestServer.TARGET_PATH;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class AddJDBCSecurityDomainTest {

    private StandaloneServer standaloneServer;
    private DomainServer domainServer;
    @ClassRule
    public static TestServer testServer = new TestServer();
    @Rule
    public TemporaryFolder tempFolder = new TemporaryFolder();
    private SecurityDomainTask task;
    private InstallationData idata;
    private TaskPrinter printer = new NoopPrinter();

    @Before
    public void setup() throws Exception {
        task = new SecurityDomainTask();
        idata = new InstallationData();
        standaloneServer = new StandaloneServer(TARGET_PATH);
        domainServer = new DomainServer(TARGET_PATH);
        idata.setTargetFolder(TARGET_PATH);
    }

    @After
    public void tearDown() throws Exception {
        standaloneServer.close();
        domainServer.close();
    }

    @Test
    public void testInstallPropertiesSecurityDomainInStandalone() throws Exception {

        final SecurityDomainTask.Config config = new SecurityDomainTask.Config();
        config.setDomainName("TestSD");
        final DatabaseSecurity.JdbcConfig jdbcFileConfig = new DatabaseSecurity.JdbcConfig();
        jdbcFileConfig.setSaltEncoding("base64");
        jdbcFileConfig.setHashEncoding("base64");
        jdbcFileConfig.setEncodingAlgorithm("simple-digest-md2");
        jdbcFileConfig.setGroupIndex("2");
        jdbcFileConfig.setPasswordIndex("1");
        jdbcFileConfig.setDatasourceName("ExampleDS");
        jdbcFileConfig.setMapperType(DatabaseSecurity.JdbcConfig.MapperType.Digest);
        jdbcFileConfig.setSqlQuery("Select * from Test");
        config.setJdbcFileConfig(jdbcFileConfig);
        idata.putConfig(config);

        standaloneServer.start("standalone.xml");
        try {
            assertTrue(task.applyToStandalone(idata, standaloneServer, printer));
        } finally {
            standaloneServer.shutdown();
        }
    }

    @Test
    public void testInstallPropertiesSecurityDomainInDomain() throws Exception {

        final SecurityDomainTask.Config config = new SecurityDomainTask.Config();
        config.setDomainName("TestSD");
        final DatabaseSecurity.JdbcConfig jdbcFileConfig = new DatabaseSecurity.JdbcConfig();
        jdbcFileConfig.setSaltEncoding("base64");
        jdbcFileConfig.setHashEncoding("base64");
        jdbcFileConfig.setEncodingAlgorithm("simple-digest-md2");
        jdbcFileConfig.setGroupIndex("2");
        jdbcFileConfig.setPasswordIndex("1");
        jdbcFileConfig.setDatasourceName("ExampleDS");
        jdbcFileConfig.setMapperType(DatabaseSecurity.JdbcConfig.MapperType.Digest);
        jdbcFileConfig.setSqlQuery("Select * from Test");
        config.setJdbcFileConfig(jdbcFileConfig);
        idata.putConfig(config);

        domainServer.start("host.xml");
        try {
            assertTrue(task.applyToDomain(idata, domainServer, printer));
        } finally {
            domainServer.shutdown();
        }
    }

    @Test
    public void testSerializeJDBCConfig() throws Exception {
        final DatabaseSecurity.JdbcConfig jdbcFileConfig = new DatabaseSecurity.JdbcConfig();
        jdbcFileConfig.setSaltEncoding("UTF-8");
        jdbcFileConfig.setHashEncoding("ASCII");
        jdbcFileConfig.setEncodingAlgorithm("hex");
        jdbcFileConfig.setGroupIndex("2");
        jdbcFileConfig.setPasswordIndex("1");
        jdbcFileConfig.setDatasourceName("test-ds");
        jdbcFileConfig.setMapperType(DatabaseSecurity.JdbcConfig.MapperType.Digest);
        jdbcFileConfig.setSqlQuery("Select * from Test");
        final SecurityDomainTask.Config config = new SecurityDomainTask.Config();
        config.setDomainName("TestSD");
        config.setJdbcFileConfig(jdbcFileConfig);
        idata.putConfig(config);

        final InstallationDataSerializer serializer = new InstallationDataSerializer(new MockLanguageUtils());
        final Path outputFile = tempFolder.newFile().toPath();
        serializer.serialize(idata, outputFile);

        final SecurityDomainTask.Config deserializedConfig = serializer.deserialize(outputFile, Optional.empty()).getConfig(SecurityDomainTask.Config.class);

        assertEquals(jdbcFileConfig, deserializedConfig.getJdbcConfig());
    }
}
