package com.ibm.emb.junit;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;

import javax.emb.MediaException;

import junit.framework.TestCase;

/**
 * This class extends junit.TestCase and is the base class for all EMB test
 * classes, allowing for easier implementations of future extensions. Error,
 * test, and tracing routines are provided along with the EMBTestConfiguration
 * singleton, which provides access to configurable properties needed to run the
 * test cases.
 */
public class EMBTestCaseBase extends TestCase {

    protected EMBTestConfiguration embTestConfig = null;

    private static String MEBTESTER_JNDI = "java:comp/env/ejb/MediaEntityLocalTestDriverHome";

    private static String TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss:SS";

    /**
     * Constructor for EMBTestCaseBase
     */
    public EMBTestCaseBase(String name) throws MediaException {
        super(name);
        // always retrieve the EMBTestConfiguration singleton
        embTestConfig = EMBTestConfiguration.instance();
        File mediaDir = new File(embTestConfig.getMediaDir());
        if (!mediaDir.exists() || !mediaDir.isDirectory()) {
            throw new MediaException("Media directory in EMBTestConfiguration property does not exit");
        }
    }

    /**
     * initialization of test cases
     */
    protected void setUp() throws Exception {
    }

    /**
     * freeup resources
     */
    protected void tearDown() throws Exception {
        removeFilesInDir(new File(embTestConfig.getMediaDir() + File.separatorChar + "Generated"));
        removeFilesInDir(new File(embTestConfig.getMediaDir() + File.separatorChar + "export"));


//
//        try {
//                InitialContext ic = new InitialContext();
//                Object ojb = ic.lookup(MEBTESTER_JNDI);
//                mebHome = (MediaEntityLocalTestDriverHome) PortableRemoteObject.narrow(ojb,
//                        MediaEntityLocalTestDriverHome.class);
//            } catch (Exception e) {
//                System.out.println("Exception while cleaning : "+e.getLocalizedMessage());
//            }
//        }
//        // create new instance of MediaEntityLocalTestDriver
//        mebTester = mebHome.create();
    }

    /**
     * Utility function used to write logging information to system out and to a
     * log file.
     */
    public void testLog(String msg) {
        SimpleDateFormat df = new SimpleDateFormat(TIMESTAMP_PATTERN);
        String timeString = df.format(new java.util.Date());
        String message = "[" + timeString + "][" + this.getName() + "][LOG][" + this.getClass().getName() + "] :" + msg;
        System.out.println(message);
        if (embTestConfig.getWriteLog()) {
            try {
                embTestConfig.getLogWriter().write(message);
                embTestConfig.getLogWriter().newLine();
                embTestConfig.getLogWriter().flush();
            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Utility function called at the end of a succeeded testcase Event is then
     * written to the test case log file an aditional message can be appended
     */
    public void succeed(String msg) {
        SimpleDateFormat df = new SimpleDateFormat(TIMESTAMP_PATTERN);
        String timeString = df.format(new java.util.Date());
        String message = "[" + timeString + "][" + this.getName() + "][SUCCEEDED][" + this.getClass().getName() + "] :"
                + msg;
        System.out.println(message);
        if (embTestConfig.getWriteLog()) {
            try {
                embTestConfig.getLogWriter().write(message);
                embTestConfig.getLogWriter().newLine();
                embTestConfig.getLogWriter().flush();
            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Utility Function called at the end of a succeded testcase Event is then
     * written to the TestCase log file
     */
    public void succeed() {
        SimpleDateFormat df = new SimpleDateFormat(TIMESTAMP_PATTERN);
        String timeString = df.format(new java.util.Date());
        String message = "[" + timeString + "][" + this.getName() + "][SUCCEEDED][" + this.getClass().getName() + "]";
        System.out.println(message);
        if (embTestConfig.getWriteLog()) {
            try {
                embTestConfig.getLogWriter().write(message);
                embTestConfig.getLogWriter().newLine();
                embTestConfig.getLogWriter().flush();
            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Utility function used to log a test suite error to system out and to the
     * log file
     */
    public void testError(String msg) {
        java.text.SimpleDateFormat df = new java.text.SimpleDateFormat(TIMESTAMP_PATTERN);
        String timeString = df.format(new java.util.Date());
        String message = "[" + timeString + "][ERROR][" + this.getName() + "][" + this.getClass().getName() + "] :"
                + msg;
        System.out.println(message);
        if (embTestConfig.getWriteLog()) {
            try {
                embTestConfig.getLogWriter().write(message);
                embTestConfig.getLogWriter().newLine();
                embTestConfig.getLogWriter().flush();
            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Utility function used to write tracing to system out and to a traceFile.
     * For the more common logging there is an additional function testLog
     */
    public void testTrace(String msg) {
        SimpleDateFormat df = new SimpleDateFormat(TIMESTAMP_PATTERN);
        String timeString = df.format(new java.util.Date());
        String message = "[" + timeString + "][" + this.getName().substring(4) + "][TRACE]["
                + this.getClass().getName() + "] :" + (msg == null ? "null" : msg);
        System.out.println(message);
        if (embTestConfig.getWriteTrace()) {
            try {
                embTestConfig.getTraceWriter().write(message);
                embTestConfig.getTraceWriter().newLine();
                embTestConfig.getTraceWriter().flush();
            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * removes files in directory used to clean up after tests
     */
    public static void removeFilesInDir(File srcDir) throws IOException {
        File[] srcFiles = srcDir.listFiles();
        if (srcFiles == null) {
            EMBStaticHelper.testTrace("file name does not point to a directory");
        } else {
            for (int i = 0; i < srcFiles.length; i++) {
                if (!(srcFiles[i].isDirectory())) {
                    srcFiles[i].delete();
                }
            }
        }
    }

    /**
     * returns a byte array of the given file's contents
     * @return Returns a byte[]
     */
    public static byte[] getByteArrayFromFile(File arg) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(arg);
        byte[] retByteArray = new byte[(int) arg.length()];
        long inputByte = fileInputStream.read(retByteArray);
        fileInputStream.close();
        return retByteArray;
    }

    /**
     * writes a known and reported error to the log if flag is enabled
     * simplifies tracking of known errors
     */
    public void logProductError(String msg) {
        if (embTestConfig.getLogKnownErrors()) {
            testLog(msg);
        }
    }

}