/*
 * ICESOFT COMMERCIAL SOURCE CODE LICENSE V 1.1
 *
 * The contents of this file are subject to the ICEsoft Commercial Source
 * Code License Agreement V1.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.icesoft.com/license/commercial-source-v1.1.html
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations under
 * the License.
 *
 * Copyright 2009-2015 ICEsoft Technologies Canada, Corp. All Rights Reserved.
 */

package com.icesoft.faces.demo.poll;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.servlet.ServletException;

import org.icepush.Configuration;
import org.icepush.ConfigurationException;
import org.icepush.servlet.ServletContextConfiguration;

@ManagedBean(name = "applicationConfiguration")
@ApplicationScoped
public class ApplicationConfiguration {
    private static final Logger LOGGER = Logger.getLogger(ApplicationConfiguration.class.getName());

    private final Configuration configuration =
        new ServletContextConfiguration(FacesUtils.getServletContext());

    public enum ContextParameter {
        DebugEnabled(
            "com.icesoft.faces.demo.poll.debugEnabled", false
        ),
        MaxTimeNoActivity(
            "com.icesoft.faces.demo.poll.maxTimeNoActivity", 1440L
        ),
        MessagingEnabled(
            "com.icesoft.faces.demo.poll.messagingEnabled", true
        ),
//        PublicHost(
//            "com.icesoft.faces.demo.poll.publicHost"
//        ),
//        PublicPort(
//            "com.icesoft.faces.demo.poll.publicPort"
//        ),
        PushMode(
            "com.icesoft.faces.demo.poll.pushMode", Constants.PushMode.PUSH
        ),
        WebLogicAdminHost(
            "weblogic.adminHost", "localhost"
        ),
        WebLogicAdminPort(
            "weblogic.adminPort", 7001
        ),
        WebLogicAdminUserName(
            "weblogic.adminUserName", "weblogic"
        ),
        WebLogicAdminPassword(
            "weblogic.adminPassword", "weblogic"
        );

        private boolean hasDefault = false;

        private String name;
        private boolean defaultBooleanValue;
        private int defaultIntValue;
        private long defaultLongValue;
        private String defaultValue;

        private ContextParameter(final String name) {
            this.name = name;
        }

        private ContextParameter(final String name, final boolean defaultBooleanValue) {
            this(name);
            this.defaultBooleanValue = defaultBooleanValue;
            this.hasDefault = true;
        }

        private ContextParameter(final String name, final int defaultIntValue) {
            this(name);
            this.defaultIntValue = defaultIntValue;
            this.hasDefault = true;
        }

        private ContextParameter(final String name, final long defaultLongValue) {
            this(name);
            this.defaultLongValue = defaultLongValue;
            this.hasDefault = true;
        }

        private ContextParameter(final String name, final String defaultValue) {
            this(name);
            this.defaultValue = defaultValue;
            this.hasDefault = true;
        }

        public String getName() {
            return name;
        }

        public boolean getDefaultBooleanValue() {
            return defaultBooleanValue;
        }

        public int getDefaultIntValue() {
            return defaultIntValue;
        }

        public long getDefaultLongValue() {
            return defaultLongValue;
        }

        public String getDefaultValue() {
            return defaultValue;
        }

        public boolean hasDefault() {
            return hasDefault;
        }
    }

    public static ApplicationConfiguration getInstance() {
        return (ApplicationConfiguration)FacesUtils.getManagedBean("applicationConfiguration");
    }

    public long getMaxTimeNoActivity() {
        return getAttributeAsLong(ContextParameter.MaxTimeNoActivity);
    }

//    public String getPublicHost() {
//        return getAttribute(ContextParameter.PublicHost);
//    }

//    public int getPublicPort() {
//        return getAttributeAsInt(ContextParameter.PublicPort);
//    }

    private String pushMode;

    public String getPushMode() {
        if (pushMode == null) {
            pushMode = getAttribute(ContextParameter.PushMode);
            if (Constants.PushMode.CLOUD_PUSH.equalsIgnoreCase(pushMode)) {
                try {
                    Class.forName("org.icefaces.mobi.component.getenhanced.GetEnhanced");
                } catch (final Exception exception) {
                    if (LOGGER.isLoggable(Level.WARNING)) {
                        LOGGER.log(
                            Level.WARNING,
                            "Unable to use Cloud Push due to the missing icefaces-ee-mobi.jar library.  Please copy " +
                                "the icefaces-ee-mobi.jar library into the [icefaces-ee-home]/samples/eps/poll/lib/ " +
                                "directory and rebuild the Poll application again.  Switching to Push now.");
                    }
                    pushMode = Constants.PushMode.PUSH;
                }
            }
        }
        return pushMode;
    }

    public String getWebLogicAdminHost() {
        return getAttribute(ContextParameter.WebLogicAdminHost);
    }

    public String getWebLogicAdminPassword() {
        return getAttribute(ContextParameter.WebLogicAdminPassword);
    }

    public int getWebLogicAdminPort() {
        return getAttributeAsInt(ContextParameter.WebLogicAdminPort);
    }

    public String getWebLogicAdminUserName() {
        return getAttribute(ContextParameter.WebLogicAdminUserName);
    }

    public boolean isDebugEnabled() {
        return getAttributeAsBoolean(ContextParameter.DebugEnabled);
    }

    public boolean isMessagingEnabled() {
        return getAttributeAsBoolean(ContextParameter.MessagingEnabled);
    }

    private String getAttribute(final ContextParameter contextParameter) {
        if (contextParameter.hasDefault()) {
            return
                configuration.getAttribute(contextParameter.getName(), contextParameter.getDefaultValue());
        } else {
            try {
                return configuration.getAttribute(contextParameter.getName());
            } catch (final ConfigurationException exception) {
                throw
                    new RuntimeException(
                        "The context-parameter '" + contextParameter.getName() + "' must be specified in the web.xml",
                        exception);
            }
        }
    }

    private int getAttributeAsInt(final ContextParameter contextParameter) {
        if (contextParameter.hasDefault()) {
            return
                configuration.getAttributeAsInteger(contextParameter.getName(), contextParameter.getDefaultIntValue());
        } else {
            try {
                return configuration.getAttributeAsInteger(contextParameter.getName());
            } catch (final ConfigurationException exception) {
                throw
                    new RuntimeException(
                        "The context-parameter '" + contextParameter.getName() + "' must be specified in the web.xml",
                        exception);
            }
        }
    }

    private boolean getAttributeAsBoolean(final ContextParameter contextParameter) {
        if (contextParameter.hasDefault()) {
            return
                configuration.getAttributeAsBoolean(contextParameter.getName(), contextParameter.getDefaultBooleanValue());
        } else {
            try {
                return configuration.getAttributeAsBoolean(contextParameter.getName());
            } catch (final ConfigurationException exception) {
                throw
                    new RuntimeException(
                        "The context-parameter '" + contextParameter.getName() + "' must be specified in the web.xml",
                        exception);
            }
        }
    }

    private long getAttributeAsLong(final ContextParameter contextParameter) {
        if (contextParameter.hasDefault()) {
            return
                configuration.getAttributeAsLong(contextParameter.getName(), contextParameter.getDefaultLongValue());
        } else {
            try {
                return configuration.getAttributeAsLong(contextParameter.getName());
            } catch (final ConfigurationException exception) {
                throw
                    new RuntimeException(
                        "The context-parameter '" + contextParameter.getName() + "' must be specified in the web.xml",
                        exception);
            }
        }
    }
}
