/*
 * This file is part of DebGen Biobank Software developed by ASTRID Research.
 * All rights reserved. Reproduction, modification, use or disclosure
 * to third parties without express authority is forbidden.
 *
 * Copyright ASTRID Research Inc., Hungary, 2009-2011.
 *
 * ASTRID Research
 * Headquaters: Csapo utca 42. Debrecen H-4029 HUNGARY
 * Phone: +36-52-533-173        Fax: +36-52-533-174
 * Web: http://www.astrid.hu    E-mail: info@astrid.hu
 *
 * Project name: DebGen Biobank Software project.
 * URLS:
 * Developers: Istvan Zoltan Nagy (istvan.nagy@astrid.hu)
 */
package hu.astrid.debgen.server.startup;

import hu.astrid.debgen.authentication.domain.DebGenUser;
import hu.astrid.debgen.exception.DebGenException;
import hu.astrid.debgen.localization.service.LocalizationService;
import hu.astrid.toucan.control.persistence.DatabaseServiceClass;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ResourceBundle;
import java.util.Scanner;

/**
 * Listener to do some startup operations
 * @author inagy
 */
public class StartupContextListener extends DatabaseServiceClass implements ServletContextListener {

    /**
     * Logger
     */
    private static final Logger logger = Logger.getLogger(StartupContextListener.class);

    /**
     * Default constructor
     */
    public StartupContextListener() {
    }

    /**
     * Starts the application, checks DB connection and localization service
     * @param event
     */
    public void contextInitialized(ServletContextEvent event) {
        Session session = null;
        logger.info("Staring up database system...");
        try {
            logger.info("Program is staring...");
            String dataSource = event.getServletContext().getInitParameter("datasource");
            logger.info("Starting up database [" + dataSource + "]...");
            init("jdbc/" + dataSource);
            session = startSession();
            session.beginTransaction();
            session.createCriteria(DebGenUser.class).add(Restrictions.eq("id", Long.valueOf(0))).list();
            session.getTransaction().commit();
            logger.info("Staring up database system...[DONE]");
        } catch (Throwable ex) {
            rollback();
            logger.error("Exception during staring up database system: ");
            logger.error(ex);
        } finally {
            closeSession();
        }
        logger.info("Testing localization service...");
        try {
            testLocale();
            logger.info("Checking localization service [DONE].");
        } catch (Throwable ex) {
            logger.error("Exception during checking localization service: ");
            logger.error(ex);
            logger.info("Falling back to default locale.");
            ApplicationParameters.fallbackToDefaultLanguage();
            logger.info("Testing default locale: [" + ApplicationParameters.getLanguageCode() + "].");
            try {
                testLocale();
                logger.info("Testing default locale: [" + ApplicationParameters.getLanguageCode() + "] ready.");
                logger.info("Checking localization service [DONE].");
            } catch (Exception e) {
                logger.error("Exception during default locale fallback: ");
                logger.error(e);
            }
        }
        logger.info("Performing temp dir cleanup.");
        try {
            String tempDir = System.getenv("TMP");
            //Query TEMP directory of the user or operating system
            if (tempDir == null || tempDir.isEmpty()) {
                tempDir = System.getenv("TEMP");
            }
            if (tempDir == null || tempDir.isEmpty()) {
                tempDir = System.getProperty("java.io.tmpdir");
            }
            if (tempDir == null || tempDir.isEmpty()) {
                throw new DebGenException("No temp directory set in the used operating system!");
            }
            File[] tempFiles = new File(tempDir).listFiles(new FilenameFilter() {

                public boolean accept(File dir, String name) {
                    return name.startsWith("report") && (name.endsWith("xml") || name.endsWith("pdf"));
                }
            });
            for (File f : tempFiles) {
                if (f.exists() && (f.lastModified() + 3600000 < System.currentTimeMillis())) {
                    boolean deleted = f.delete();
                    if (!deleted) {
                        logger.error("Can't delete file: "+f.getAbsolutePath());
                    }
                }
            }
        } catch (Exception e) {
            logger.error("Exception during cleanup: ");
            logger.error(e);
        }
    }

    /**
     * Destroys
     * @param sce
     */
    public void contextDestroyed(ServletContextEvent sce) {
        /* DO NOTHING, context can be destroyed
         *
         */
    }

    /**
     * Tests the given local
     * @throws Exception When the test fails
     */
    private void testLocale() throws Exception {
        Scanner scanner = null;
        try {
            LocalizationService ls = new LocalizationService();
            ResourceBundle db = ls.getDefaultBundle();
            String key = db.getKeys().nextElement();
            if (db.getLocale().getISO3Language().equals(ApplicationParameters.getLanguageCode())) {
                logger.info("ResourceBundle found.");
            } else {
                throw new Exception("This ResourceBundle is a fallback: Expected [" + ApplicationParameters.getLanguageCode() + "], found [" + db.getLocale().getISO3Language() + "]");
            }
            db.getString(key);
            logger.info("Test key loaded successfully.");
            logger.info("Checking test mail template.");
            scanner = new Scanner(StartupContextListener.class.getResource("/hu/astrid/debgen/mail/template/" + ApplicationParameters.getLanguageCode() + "/forgottenpassword.html").openStream());
            logger.info("Stream opened to test mail template.");
            scanner.nextLine();
        } catch (IOException ex) {
            throw ex;
        } finally {
            try {
                scanner.close();
            } catch (Exception ex) {
            }
        }
    }
}
