/*
 * 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.utils.log.impl;

import com.queplix.core.integrator.security.AccessRightsManager;
import com.queplix.core.integrator.security.NoSuchGroupException;
import com.queplix.core.integrator.security.NoSuchUserException;
import com.queplix.core.integrator.security.User;
import com.queplix.core.modules.mail.MailAddress;
import com.queplix.core.utils.StringHelper;
import com.queplix.core.utils.log.AbstractLogger;
import com.queplix.core.utils.sql.SqlWrapper;
import com.queplix.core.utils.sql.SqlWrapperFactory;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;

/**
 * Mail LOG configurator.
 *
 * @author [ALB] Andrey Baranov
 * @version $Revision: 1.1.1.1 $ $Date: 2005/09/12 15:31:02 $
 */

final class MailLogConfigurator
        extends AbstractLogger {

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

    private static final String SQL =
            "SELECT " +
                    " TARGET_CLASS_MASK, " +
                    " MESSAGE_HND_CLASS, " +
                    " EMAILS, " +
                    " EMPLOYEE_ID, " +
                    " WORKGROUP_ID " +
                    "FROM " +
                    " QX_ERROR_CFG " +
                    "WHERE " +
                    " DISABLE != 1 " +
                    "ORDER BY " +
                    " ERROR_CFG_ID";

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

    private MailLogRecord record;
    private boolean isDisabled = false;
    private Collection vos = new ArrayList();

    // ----------------------------------------------------- constructor

    public MailLogConfigurator(MailLogRecord record) {
        this.record = record;

        // init.
        init();
    }

    // ----------------------------------------------------- getters

    public boolean isDisabled() {
        return isDisabled || (vos.size() == 0);
    }

    public ConfigVO[] getVOArray() {
        if(isDisabled()) {
            throw new IllegalStateException("Logging is disabled");
        }
        return (ConfigVO[]) vos.toArray(new ConfigVO[0]);
    }

    // ----------------------------------------------------- private method

    //
    // Intialization.
    //

    private void init() {

        String logSenderClassName = record.getSenderClass();

        // select data from error log config table
        SqlWrapper sqlW = SqlWrapperFactory.getSqlWrapper();
        Connection con = null;
        Statement stat = null;

        try {
            con = sqlW.doConnection();
            stat = sqlW.doStatement(con);

            ResultSet rs = sqlW.executeQuery(stat, SQL);
            while(rs.next()) {
                String classMask = rs.getString(1).trim();
                int length = classMask.length();

                // check target class mask
                // ex:
                //		1) *
                //		2) com.queplix.*
                //		3) com.queplic.core.SomeClass

                boolean match;
                if(classMask.charAt(length - 1) == '*') {
                    classMask = classMask.substring(0, length - 1);
                    if(classMask.length() == 0) {
                        match = true;
                    } else {
                        match = (logSenderClassName.indexOf(classMask) == 0);
                    }
                } else {
                    match = logSenderClassName.equals(classMask);
                }
                if(!match) {
                    continue;
                }

                // ...seems like enabled

                // create new VO
                ConfigVO vo = new ConfigVO();

                // initialize VO
                initMessageHndClass(vo, rs.getString(2));

                String mails = rs.getString(3);
                if(mails != null) {
                    initMails(vo, mails);
                }

                long employee = rs.getLong(4);
                if(!rs.wasNull()) {
                    initEmplMails(vo, employee);
                }

                long workgroup = rs.getLong(5);
                if(!rs.wasNull()) {
                    initWgMails(vo, workgroup);
                }

                // add VO in collection
                if(vo.getMailAddresses() != null) {
                    vos.add(vo);
                }
            }

        } catch (SQLException ex) {
            // simple write log
            ERROR(ex);
            isDisabled = true;

        } catch (Exception ex) {
            // simple write log
            ERROR(ex);
            isDisabled = true;

        } finally {
            sqlW.closeConnection(con, stat);
        }
    }

    //
    // Init log message handler class
    //
    private void initMessageHndClass(ConfigVO vo, String className)
            throws Exception {

        MailMessageHandler msgHnd = (MailMessageHandler) Class.forName(
                className).newInstance();
        msgHnd.setLogRecord(record);
        msgHnd.init();
        vo.setMailMessageHnd(msgHnd);
    }

    //
    // Init emails
    //
    private void initMails(ConfigVO vo, String emails) {

        if(emails == null) {
            WARN("Got emtpty email");
            return;
        }

        MailAddress[] addrs = MailAddress.parse(emails);
        for(int i = 0; i < addrs.length; i++) {
            // add email in collection
            vo.addMailAddresse(addrs[i]);
        }
    }

    //
    // Init workgroup emails
    //
    private void initEmplMails(ConfigVO vo, long employee_id)
            throws NoSuchUserException {

        // Get employee VO.
        User user = AccessRightsManager.getUser(employee_id);
        if(!StringHelper.isEmpty(user.getEmail())) {
            // user has e-mail - add in collection
            vo.addMailAddresse(new MailAddress(user));
        }
    }

    //
    // Init workgroup emails
    //
    private void initWgMails(ConfigVO vo, long workgroup_id)
            throws NoSuchGroupException {

        try {
            // Get users for group.
            Collection<User> users = AccessRightsManager.getUsersInGroup(
                    workgroup_id);
            if(users.size() == 0) {
                WARN("Can't find any user for group #" + workgroup_id);
            }
            for(User user : users) {
                if(!StringHelper.isEmpty(user.getEmail())) {
                    // user has e-mail - add in collection
                    vo.addMailAddresse(new MailAddress(user));
                }
            }
        } catch (NoSuchGroupException e) {
            ERROR("Can't find any user for group #" + workgroup_id);
        }
    }

    // ----------------------------------------------------- inner class

    /**
     * <p>Special VO class</p>
     *
     * @author [ALB] Baranov Andrey
     * @version 1.0
     */
    public static class ConfigVO
            implements java.io.Serializable {

        private MailMessageHandler msgHnd;
        private Collection mailAddresses = new HashSet();

        public MailMessageHandler getMsgHnd() {
            return msgHnd;
        }

        public MailAddress[] getMailAddresses() {
            return (MailAddress[]) mailAddresses.toArray(new MailAddress[0]);
        }

        void setMailMessageHnd(MailMessageHandler msgHnd) {
            this.msgHnd = msgHnd;
        }

        void addMailAddresse(MailAddress ma) {
            mailAddresses.add(ma);
        }
    }
}
