/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * 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 com.queplix.core.modules.services;

import com.queplix.core.integrator.security.AccessRightsManager;
import com.queplix.core.integrator.security.User;
import com.queplix.core.modules.config.ejb.UserPropertyManagerLocal;
import com.queplix.core.modules.config.ejb.UserPropertyManagerLocalHome;
import com.queplix.core.utils.JNDINames;
import com.queplix.core.utils.StringHelper;
import com.queplix.core.utils.cache.CacheObjectManager;
import com.queplix.core.utils.dao.AbstractPropertyFactory;

import java.io.File;
import java.util.Properties;

/**
 * <p>Initialize QW services (scheduler and tools) manager</p>
 *
 * @author Baranov Andrey [ALB]
 * @version $Revision: 1.1 $ $Date: 2006/04/18 12:04:16 $
 */

public final class ServiceInitManager {

    // ----------------------------------------------------- constants

    private static final Class CLASS = ServiceInitManager.class;
    private static final String FILE_NAME = "services.init.properties";

    // file properties parameters
    public static final String FP_SCHEDULER_CMD_PARAM = "SCHEDULER_CMD";
    public static final String FP_SCHEDULER_AUTOSTART_PARAM
            = "SCHEDULER_AUTOSTART";

    // file properties values
    private static String FP_SCHEDULER_CMD;
    private static boolean FP_SCHEDULER_AUTOSTART;

    // user properties parameters
    public static final String UP_XMLMETA_PARAM = "__xmlmeta_";
    public static final String UP_XMLMETA_DIRS_PARAM = UP_XMLMETA_PARAM
            + "dirs";
    public static final String UP_ENTITY_XML_DIR_DIGEST_PARAM = UP_XMLMETA_PARAM
            + "entityDirDigest_";
    public static final String UP_FOCUS_XML_DIR_DIGEST_PARAM = UP_XMLMETA_PARAM
            + "focusDirDigest_";
    public static final String UP_CONTEXTMENU_XML_FILE_DIGEST_PARAM =
            UP_XMLMETA_PARAM + "contextMenuFileDigest_";
    public static final String UP_SYSTEM_CHARTS_XML_DIRS_DIGEST_PARAM =
            UP_XMLMETA_PARAM + "systemChartsDirDigest_";
    public static final String UP_PORTALS_CONFIG_DIGEST_PARAM =
            UP_XMLMETA_PARAM + "portalsConfigFileDigest";
    public static final String UP_SCRIPT_XML_FILE_DIGEST_PARAM =
            UP_XMLMETA_PARAM + "scriptFileDigest_";
    public static final String UP_CUSTOM_XML_DIR_DIGEST_PARAM = UP_XMLMETA_PARAM
            + "customDirDigest_";
    public static final String UP_SCHEDULER_CMD_PARAM = "__schedulerCmd";
    public static final String UP_SCHEDULER_AUTOSTART_PARAM
            = "__schedulerAutostart";
    public static final String UP_XMLMETA_PATH_PARAM = "__xmlmetaPath";


    // file properties loading...
    static {
        try {
            Properties props = new Properties();
            props.load(AbstractPropertyFactory.loadSysPropertiesAsStream(CLASS,
                    FILE_NAME));

            FP_SCHEDULER_CMD = (String) props.get(FP_SCHEDULER_CMD_PARAM);
            String s = (String) props.get(FP_SCHEDULER_AUTOSTART_PARAM);
            FP_SCHEDULER_AUTOSTART = (s != null && s.trim().equalsIgnoreCase(
                    "true"));

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    // ----------------------------------------------------- variables

    private final static CacheObjectManager com = new CacheObjectManager();
    private final User user;

    // ----------------------------------------------------- public methods

    /**
     * Constructor.
     */
    public ServiceInitManager() {
        user = AccessRightsManager.getSystemLogonSession().getUser();
    }

    private final static String ENTITY_SUB_DIR = "entity";
    private final static String FOCUS_SUB_DIR = "form";
    private final static String CONTEXTMENU_SUB_DIR = "context-menu";
    private final static String SCRIPT_XML_FILE = "scripts.xml";
    private final static String CUSTOM_SUB_DIR = "custom";
    private final static String I18N_SUB_DIR = "i18n";
    private final static String SYSTEM_CHARTS_SUB_DIR = "chart";

    
    private String xmlMetaDir;
    private String entityMetaDir;
    private String scriptMetaFile;
    private String customMetaDir;
    private String i18nMetaDir;


    public ServiceInitManager(String xmlMetaDir) {
        this();

        if(StringHelper.isEmpty(xmlMetaDir)) {
            throw new IllegalArgumentException(
                    "Passed parameter xmlMetaDir is empty");
        }

        this.xmlMetaDir = xmlMetaDir;
    }

    public String getXmlMetaDir() {
        return xmlMetaDir;
    }

    //
    // GETTERS.
    //

    /**
     * Returns last launched xmlmeta path from database.
     *
     * @return last launched xmlmeta path.
     */
    public String getXmlMetaPath() {
        String xmlMetaPath = getUserProperty(UP_XMLMETA_PATH_PARAM);
        return xmlMetaPath == null ? StringHelper.EMPTY_VALUE:xmlMetaPath;
    }

    /**
     * Get entity tools XML dir location.
     *
     * @return some file path
     */
    public String getEntityXmlDir() {
        if(entityMetaDir == null) {
            entityMetaDir = new File(xmlMetaDir, ENTITY_SUB_DIR)
                    .getAbsolutePath();
        }
        return entityMetaDir;
    }

    /**
     * Get entity tools XML dir digest.
     * Digest is a value that uniquely represents the directory contents. Its
     * used to identify if the directory content has changed or not. An
     * example of digest can be directory size.
     *
     * @return digest string
     */
    public String getEntityXmlDirDigest() {
        String digest = getUserProperty(getPropId(
                UP_ENTITY_XML_DIR_DIGEST_PARAM));
        if(digest == null) {
            digest = "";
        }
        return digest;
    }

    /**
     * Get form tools XML dir location.
     *
     * @param xmlMetaDir base xml meta dir
     * @return some file path
     */
    public static String getFocusXmlDir(String xmlMetaDir) {
        return new File(xmlMetaDir, FOCUS_SUB_DIR).getAbsolutePath();
    }

    /**
     * Get form tools XML dir digest, for the given user.
     * Digest is a value that uniquely represents the directory contents. Its
     * used to identify if the directory content has changed or not. An
     * example of digest can be directory size.
     *
     * @param user       given user
     * @param xmlMetaDir base xml meta dir
     * @return digest string
     */
    public static String getFocusXmlDirDigest(User user, String xmlMetaDir) {
        String digest = getUserProperty(getPropId(UP_FOCUS_XML_DIR_DIGEST_PARAM,
                xmlMetaDir), user);
        if(digest == null) {
            digest = "";
        }
        return digest;
    }

    /**
     * Get system charts directory location.
     *
     * @param xmlMetaDir base xml meta dir
     */
    public static String getSystemChartsXmlDir(String xmlMetaDir) {
        return new File(xmlMetaDir,
                SYSTEM_CHARTS_SUB_DIR).getAbsolutePath();
    }
    
    public static String getPortalsConfigSize(User user, String xmlMetaDir) {
        String digest = getUserProperty(getPropId(
            UP_PORTALS_CONFIG_DIGEST_PARAM, xmlMetaDir), user);
        if(digest == null) {
            digest = "";
        }
        return digest;
    }

    /**
     * Get system charts directory digest.
     * Digest is a value that uniquely represents the directory contents. Its
     * used to identify if the directory content has changed or not. An
     * example of digest can be directory size.
     *
     * @return digest string
     */
    public static String getSystemChartsXmlDirDigest(User user, String xmlMetaDir) {
        String digest = getUserProperty(getPropId(
                UP_SYSTEM_CHARTS_XML_DIRS_DIGEST_PARAM, xmlMetaDir), user);
        if(digest == null) {
            digest = "";
        }
        return digest;
    }


    /**
     * Get context menu tools XML file location.
     *
     * @param xmlMetaDir base xml meta dir
     * @return some file path
     */
    public static String getContextMenuXmlDir(String xmlMetaDir) {
        return new File(getFocusXmlDir(xmlMetaDir), CONTEXTMENU_SUB_DIR)
                .getAbsolutePath();
    }

    /**
     * Get context menu tools XML file digest.
     * Digest is a value that uniquely represents the directory contents. Its
     * used to identify if the directory content has changed or not. An
     * example of digest can be directory size.
     *
     * @return digest string
     */
    public String getContextMenuXmlFileDigest() {
        String digest = getUserProperty(getPropId(
                UP_CONTEXTMENU_XML_FILE_DIGEST_PARAM));
        if(digest == null) {
            digest = "";
        }
        return digest;
    }

    /**
     * Get script tools XML file location.
     *
     * @return some file path
     */
    public String getScriptXmlFile() {
        if(scriptMetaFile == null) {
            scriptMetaFile = new File(xmlMetaDir, SCRIPT_XML_FILE)
                    .getAbsolutePath();
        }
        return scriptMetaFile;
    }

    /**
     * Get script tools XML file digest.
     * Digest is a value that uniquely represents the directory contents. Its
     * used to identify if the directory content has changed or not. An
     * example of digest can be directory size.
     *
     * @return digest string
     */
    public String getScriptXmlFileDigest() {
        String digest = getUserProperty(getPropId(
                UP_SCRIPT_XML_FILE_DIGEST_PARAM));
        if(digest == null) {
            digest = "";
        }
        return digest;
    }

    /**
     * Get custom tools XML dir location.
     *
     * @return some file path
     */
    public String getCustomXmlDir() {
        if(customMetaDir == null) {
            customMetaDir = new File(xmlMetaDir, CUSTOM_SUB_DIR)
                    .getAbsolutePath();
        }
        return customMetaDir;
    }

    /**
     * Get custom tools XML dir digest.
     * Digest is a value that uniquely represents the directory contents. Its
     * used to identify if the directory content has changed or not. An
     * example of digest can be directory size.
     *
     * @return digest string
     */
    public String getCustomXmlDirDigest() {
        String digest = getUserProperty(getPropId(
                UP_CUSTOM_XML_DIR_DIGEST_PARAM));
        if(digest == null) {
            digest = "";
        }
        return digest;
    }

    /**
     * Get custom tools I18N XML dir location.
     *
     * @return some file path
     */
    public String getI18nXmlDir() {
        if(i18nMetaDir == null) {
            i18nMetaDir = new File(getCustomXmlDir(), I18N_SUB_DIR)
                    .getAbsolutePath();
        }
        return i18nMetaDir;
    }

    /**
     * Get scheduler startup script.
     *
     * @return some script
     */
    public String getSchedulerCmd() {
        String cmd = getUserProperty(UP_SCHEDULER_CMD_PARAM);
        if(cmd == null) {
            cmd = FP_SCHEDULER_CMD;
        }
        return cmd;
    }

    /**
     * Get scheduler auto startup script flag.
     *
     * @return flag
     */
    public boolean getSchedulerAutostart() {
        String s = getUserProperty(UP_SCHEDULER_AUTOSTART_PARAM);

        boolean flag;
        if(s == null) {
            flag = FP_SCHEDULER_AUTOSTART;
        } else {
            flag = s.trim().equalsIgnoreCase("true");
        }

        return flag;
    }

    /**
     * Get scheduler startup command.
     *
     * @return some command
     */
    public String getSchedulerStartCmd() {
        return getSchedulerCmd() + " start";
    }

    /**
     * Get scheduler stop command.
     *
     * @return some command
     */
    public String getSchedulerStopCmd() {
        return getSchedulerCmd() + " stop";
    }

    /**
     * Get scheduler status command.
     *
     * @return some command
     */
    public String getSchedulerStatusCmd() {
        return getSchedulerCmd() + " status";
    }

    //
    // SETTERS.
    //

    /**
     * Stores last launched xmlmeta path to the database.
     *
     * @param value launched xmlmeta path.
     */
    public void setXmlMetaPath(String value) {
        setUserProperty(UP_XMLMETA_PATH_PARAM, value);
    }

    /**
     * Set entity tool XML dir digest.
     *
     * @param value new value
     */
    public void setEntityXmlDirDigest(String value) {
        setUserProperty(getPropId(UP_ENTITY_XML_DIR_DIGEST_PARAM), value);
    }

    /**
     * Set focus tool XML dir digest.
     *
     * @param value       new value
     * @param user        user to save param
     * @param xmlMetaDirs meta dirs
     */
    public static void setFocusXmlDirDigest(String value, String xmlMetaDirs,
                                            User user) {
        setUserProperty(getPropId(UP_FOCUS_XML_DIR_DIGEST_PARAM, xmlMetaDirs),
                value, user);
    }

    /**
     * Set system charts directory digest.
     *
     * @param value new value
     */
    public static void setSystemChartsXmlDirDigest(
            String value, String xmlMetaDirs, User user) {
        setUserProperty(getPropId(
                UP_SYSTEM_CHARTS_XML_DIRS_DIGEST_PARAM, xmlMetaDirs), value, user);
    }
    
    public static void setPortalsConfigDigest(
        String value, String xmlMetaDir, User user) {
        setUserProperty(getPropId(UP_PORTALS_CONFIG_DIGEST_PARAM, xmlMetaDir),
            value, user);
    }

    /**
     * Set context menu tool XML file digest.
     *
     * @param value new value
     */
    public void setContextMenuXmlFileDigest(String value) {
        setUserProperty(getPropId(UP_CONTEXTMENU_XML_FILE_DIGEST_PARAM), value);
    }

    /**
     * Set script tool XML file digest.
     *
     * @param value new value
     */
    public void setScriptXmlFileDigest(String value) {
        setUserProperty(getPropId(UP_SCRIPT_XML_FILE_DIGEST_PARAM), value);
    }

    /**
     * Set custom tool XML dir digest.
     *
     * @param value new value
     */
    public void setCustomXmlDirDigest(String value) {
        setUserProperty(getPropId(UP_CUSTOM_XML_DIR_DIGEST_PARAM), value);
    }

    /**
     * Set scheduler startup script.
     *
     * @param value new value
     */
    public void setSchedulerCmd(String value) {
        setUserProperty(UP_SCHEDULER_CMD_PARAM, value);
    }

    /**
     * Set scheduler auto startup flag script.
     *
     * @param value new value
     */
    public void setSchedulerAutostart(boolean value) {
        setUserProperty(UP_SCHEDULER_AUTOSTART_PARAM, "" + value);
    }

    // ----------------------------------------------------- private methods

    private String getPropId(String propId) {
        return getPropId(propId, xmlMetaDir);
    }

    private static String getUserProperty(String propId, User user) {
        return getUserPropertyManager().getUserProperty(propId, user);
    }

    private static String getPropId(String propId, String xmlMetaDir) {
        String id = propId;
        if(xmlMetaDir != null) {
            id += xmlMetaDir;
        }
        return id;
    }

    /**
     * Get user property by <code>propId</code> property ID.
     *
     * @param propId property ID
     * @return property value
     */
    private String getUserProperty(String propId) {
        return getUserPropertyManager().getUserProperty(propId, user);
    }

    /**
     * Set user property <code>propId</code>.
     *
     * @param propId property ID
     * @param value  property value
     */
    private void setUserProperty(String propId, String value) {
        setUserProperty(propId, value, user);
    }

    public static void setUserProperty(String propId, String value, User user) {
        getUserPropertyManager().setUserProperty(propId, value, user);
    }

    /**
     * Get UserPropertyManagerEJB local interface.
     *
     * @return UserPropertyManagerLocal object
     */
    private static UserPropertyManagerLocal getUserPropertyManager() {
        return (UserPropertyManagerLocal) com.getLocalObject(
                JNDINames.UserPropertyManager,
                UserPropertyManagerLocalHome.class);
    }
}
