/*                          
 * mBench: The Open Source Micro Benchmark Tool 
 *                                             
 * Distributable under GPL license. 
 * See terms of license at gnu.org.                 
 *
 * Copyright (C) 2005 Sumisho Computer Systems Corp.
 */
package test.jp.co.scs.mbench;

import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;

import jp.co.scs.mbench.BenchmarkInfo;
import jp.co.scs.mbench.DocumentUtil;
import jp.co.scs.mbench.FinalizerInfo;
import jp.co.scs.mbench.InitializerInfo;
import jp.co.scs.mbench.MultiNodeInfo;
import jp.co.scs.mbench.MultiServerInfo;
import jp.co.scs.mbench.jdbc.DataSourceInfo;
import junit.framework.TestCase;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 *      @author Toshio Sugahara
 */
public class DocumentUtilTest extends TestCase {

    private static final String NON_FORMAL_FILE =
        "data/DocumentUtil/nonformal.xml";

    private static final String INITIALIZER_NAME = "Schema01-initializer";

    private static final String INITIALIZER_CLASS_NAME = 
        "jp.co.scs.mbench.component.Schema01Initializer";
    
    private static final String FINALIZER_NAME = "Schema01-finalizer";

    private static final String FINALIZER_CLASS_NAME = 
        "jp.co.scs.mbench.component.Schema01Finalizer";

    private static final String DATA_SOURCE_NAME = "a4";
    
    private static final String PROTOCOL_NAME = "mysql";
    
    private static final String DRIVER_NAME = "com.mysql.jdbc.Driver";
    
    private static final String HOST_NAME = "127.0.0.1";
    
    private static final String PORT_NUMBER = "3306";
    
    private static final String DB_NAME = "test";
    
    private static final String USER_NAME = "hoge";
    
    private static final String PASSWORD = "foo";
    
    private static final String USEUNICODE = "true";
    
    private static final String CHARACTERENCODING = "MS932";

    private static final String BENCHMARK_NAME = "Schema01-benchmark";

    private static final String BENCHMARK_CLASS_NAME = 
        "jp.co.scs.mbench.component.Schema01Benchmark";

    private static final String MULTI_CLIENT_NAME = "aaa";

    private static final String MULTI_CLIENT_TYPE = "primary";
    
    private static final String MULTI_CLIENT_HOST_NAME = "192.168.11.1";
    
    private static final String MULTI_CLIENT_PORT = "5001";
    
    private static final String MULTI_CLIENT_SECONDARY_HOST_NAME = "192.168.11.1";
    
    private static final String MULTI_CLIENT_SECONDARY_PORT = "5002";
    
    private static final String MULTI_SERVER_NAME = "abc";
    
    private static final String MULTI_SERVER_CONNECT = "server";
    
    private static final String CONFIGURATION_FILE_NAME = "conf/mbench.xml";
    
    private static final String DEFAULT_DIR = "conf";
    
    private static final String TEMP_DIR = "temp";

    private static final String TEST_CONFIGURATION_FILE_NAME1 = 
        "data/DocumentUtil/mbench.xml";
    
    /**
     *  Get the DOM document from configuration form.
     */
    public void testGetDocument() {
        Document document = null;
        try {
            document = DocumentUtil.getDocument();
        } catch (IOException ex) {
            fail(ex.getMessage());
        } catch (ParserConfigurationException ex) {
            fail(ex.getMessage());
        } catch (SAXException ex) {
            fail(ex.getMessage());
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
        
        assertNotNull(document);
    }

    /**
     *  SAXException must be thrown if configuration cannot be parsed.
     */
    public void testGetDocument2() {
        try {
            DocumentUtil.getDocument(NON_FORMAL_FILE);
            fail();
        } catch (IOException ex) {
            fail(ex.getMessage());
        } catch (ParserConfigurationException ex) {
            fail(ex.getMessage());
        } catch (SAXException ex) {
            assertTrue(SAXException.class.isAssignableFrom(ex.getClass()));
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }

    /**
     *  Get the initializer information from configuration file
     *  by specific name.
     */
    public void testGetInitializerInfo() {
        try {
            FileUtil.copyFiles(CONFIGURATION_FILE_NAME, TEMP_DIR);
            FileUtil.deleteFile(CONFIGURATION_FILE_NAME);
            FileUtil.copyFiles(TEST_CONFIGURATION_FILE_NAME1, DEFAULT_DIR);
            DocumentUtil.getDocument();
            InitializerInfo initializerInfo =
                DocumentUtil.getInitializerInfo(INITIALIZER_NAME);

            assertEquals(INITIALIZER_NAME, initializerInfo.getName());
            assertEquals(INITIALIZER_CLASS_NAME, initializerInfo.getClassName());            
        } catch (IOException ex) {
            fail(ex.getMessage());
        } catch (ParserConfigurationException ex) {
            fail(ex.getMessage());
        } catch (SAXException ex) {
            fail(ex.getMessage());
        } catch (Exception ex) {
            fail(ex.getMessage());
        } finally {
            try {
                FileUtil.copyFiles(TEMP_DIR, DEFAULT_DIR);
            } catch (Exception ex) {
                fail(ex.getMessage());
            } finally {
                FileUtil.deleteFile(TEMP_DIR);
            }
        }
    }
    
    /**
     *  Get the finalizer information from configuration file
     *  by specific name.
     */
    public void testGetFinalizerInfo() {
        try {
            FileUtil.copyFiles(CONFIGURATION_FILE_NAME, TEMP_DIR);
            FileUtil.deleteFile(CONFIGURATION_FILE_NAME);
            FileUtil.copyFiles(TEST_CONFIGURATION_FILE_NAME1, DEFAULT_DIR);
            DocumentUtil.getDocument();
            FinalizerInfo finalizerInfo =
                DocumentUtil.getFinalizerInfo(FINALIZER_NAME);

            assertEquals(FINALIZER_NAME, finalizerInfo.getName());
            assertEquals(FINALIZER_CLASS_NAME, finalizerInfo.getClassName());            
        } catch (IOException ex) {
            fail(ex.getMessage());
        } catch (ParserConfigurationException ex) {
            fail(ex.getMessage());
        } catch (SAXException ex) {
            fail(ex.getMessage());
        } catch (Exception ex) {
            fail(ex.getMessage());
        } finally {
            try {
                FileUtil.copyFiles(TEMP_DIR, DEFAULT_DIR);
            } catch (Exception ex) {
                fail(ex.getMessage());
            } finally {
                FileUtil.deleteFile(TEMP_DIR);
            }
        }
    }
    
    /**
     *  Get the data source information from configuration file
     *  by specific name.
     */
    public void testGetDataSourceInfo() {
        try {
            FileUtil.copyFiles(CONFIGURATION_FILE_NAME, TEMP_DIR);
            FileUtil.deleteFile(CONFIGURATION_FILE_NAME);
            FileUtil.copyFiles(TEST_CONFIGURATION_FILE_NAME1, DEFAULT_DIR);
            DocumentUtil.getDocument();
            DataSourceInfo dataSourceInfo =
                DocumentUtil.getDataSourceInfo(DATA_SOURCE_NAME);

            assertEquals(DATA_SOURCE_NAME, dataSourceInfo.getName());
            assertEquals(PROTOCOL_NAME, dataSourceInfo.getProtocol());
            assertEquals(DRIVER_NAME, dataSourceInfo.getDriver());
            assertEquals(HOST_NAME, dataSourceInfo.getHost());
            assertEquals(PORT_NUMBER, dataSourceInfo.getPort());
            assertEquals(DB_NAME, dataSourceInfo.getDB());
            assertEquals(USER_NAME, dataSourceInfo.getUser());
            assertEquals(PASSWORD, dataSourceInfo.getPassword());
            assertEquals(USEUNICODE, dataSourceInfo.getUseUnicode());
            assertEquals(CHARACTERENCODING, dataSourceInfo.getCharacterEncoding());
        } catch (IOException ex) {
            fail(ex.getMessage());
        } catch (ParserConfigurationException ex) {
            fail(ex.getMessage());
        } catch (SAXException ex) {
            fail(ex.getMessage());
        } catch (Exception ex) {
            fail(ex.getMessage());
        } finally {
            try {
                FileUtil.copyFiles(TEMP_DIR, DEFAULT_DIR);
            } catch (Exception ex) {
                fail(ex.getMessage());
            } finally {
                FileUtil.deleteFile(TEMP_DIR);
            }
        }
    }

    /**
     *  Get the benchmark information from configuration file
     *  by specific name.
     */
    public void testGetBenchmarkInfo() {
        try {
            FileUtil.copyFiles(CONFIGURATION_FILE_NAME, TEMP_DIR);
            FileUtil.deleteFile(CONFIGURATION_FILE_NAME);
            FileUtil.copyFiles(TEST_CONFIGURATION_FILE_NAME1, DEFAULT_DIR);
            DocumentUtil.getDocument();
            BenchmarkInfo benchmarkInfo =
                DocumentUtil.getBenchmarkInfo(BENCHMARK_NAME);

            assertEquals(BENCHMARK_NAME, benchmarkInfo.getName());
            assertEquals(BENCHMARK_CLASS_NAME, benchmarkInfo.getClassName());
        } catch (IOException ex) {
            fail(ex.getMessage());
        } catch (ParserConfigurationException ex) {
            fail(ex.getMessage());
        } catch (SAXException ex) {
            fail(ex.getMessage());
        } catch (Exception ex) {
            fail(ex.getMessage());
        } finally {
            try {
                FileUtil.copyFiles(TEMP_DIR, DEFAULT_DIR);
            } catch (Exception ex) {
                fail(ex.getMessage());
            } finally {
                FileUtil.deleteFile(TEMP_DIR);
            }
        }
    }

    /**
     *  Get the multiple node information from configuration file
     *  by specific name.
     */
    public void testGetMultiNodeInfo() {
        try {
            FileUtil.copyFiles(CONFIGURATION_FILE_NAME, TEMP_DIR);
            FileUtil.deleteFile(CONFIGURATION_FILE_NAME);
            FileUtil.copyFiles(TEST_CONFIGURATION_FILE_NAME1, DEFAULT_DIR);
            DocumentUtil.getDocument();
            MultiNodeInfo multiNodeInfo =
                DocumentUtil.getMultiNodeInfo(MULTI_CLIENT_NAME);

            assertEquals(MULTI_CLIENT_NAME, multiNodeInfo.getName());
            assertEquals(MULTI_CLIENT_TYPE, multiNodeInfo.getNodeType());
            assertEquals(MULTI_CLIENT_HOST_NAME, multiNodeInfo.getLocalHost());
            assertEquals(MULTI_CLIENT_PORT, String.valueOf(multiNodeInfo.getLocalPort()));

            String[] socondaryHosts = multiNodeInfo.getSecondaryHost();
            assertEquals(1, socondaryHosts.length);

            for (int i = 0; i < socondaryHosts.length; i++) { 
                assertEquals(MULTI_CLIENT_SECONDARY_HOST_NAME, socondaryHosts[i]);
            }

            int[] socondaryPorts = multiNodeInfo.getSecondaryPort();
            assertEquals(1, socondaryPorts.length);

            for (int i = 0; i < socondaryPorts.length; i++) {
                assertEquals(MULTI_CLIENT_SECONDARY_PORT, String.valueOf(socondaryPorts[i]));   
            }
        } catch (IOException ex) {
            fail(ex.getMessage());
        } catch (ParserConfigurationException ex) {
            fail(ex.getMessage());
        } catch (SAXException ex) {
            fail(ex.getMessage());
        } catch (Exception ex) {
            fail(ex.getMessage());
        } finally {
            try {
                FileUtil.copyFiles(TEMP_DIR, DEFAULT_DIR);
            } catch (Exception ex) {
                fail(ex.getMessage());
            } finally {
                FileUtil.deleteFile(TEMP_DIR);
            }
        }
    }

    /**
     *  Get the multiple server information from configuration file
     *  by specific name.
     */
    public void testGetMultiServerInfo() {
        try {
            FileUtil.copyFiles(CONFIGURATION_FILE_NAME, TEMP_DIR);
            FileUtil.deleteFile(CONFIGURATION_FILE_NAME);
            FileUtil.copyFiles(TEST_CONFIGURATION_FILE_NAME1, DEFAULT_DIR);
            DocumentUtil.getDocument();
            MultiServerInfo multiServerInfo =
                DocumentUtil.getMultiServerInfo(MULTI_SERVER_NAME);

            assertEquals(MULTI_SERVER_NAME, multiServerInfo.getName());
            
            String[] connects = multiServerInfo.getConnect();
            
            assertEquals(3, connects.length);
            
            for (int i = 0; i < connects.length; i++) {
                assertEquals(MULTI_SERVER_CONNECT + (i+1), connects[i]);
            }
        } catch (IOException ex) {
            fail(ex.getMessage());
        } catch (ParserConfigurationException ex) {
            fail(ex.getMessage());
        } catch (SAXException ex) {
            fail(ex.getMessage());
        } catch (Exception ex) {
            fail(ex.getMessage());
        } finally {
            try {
                FileUtil.copyFiles(TEMP_DIR, DEFAULT_DIR);
            } catch (Exception ex) {
                fail(ex.getMessage());
            } finally {
                FileUtil.deleteFile(TEMP_DIR);
            }
        }
    }
}
