package gov.va.vinci.dart;

import gov.va.vinci.dart.dms.biz.Repository;
import gov.va.vinci.dart.usr.UserManagerImpl;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

/**
 * Provides access to the <code>app.properties</code> values. The values are selected using the
 * Cocoon mode system property. The class static members are set in the <code>applicationContext.xml</code>
 * file. The Spring framework invokes the <code>afterPropertiesSet()</code> method during initialization,
 *
 * Date: 7/23/13
 * Time: 2:36 PM
 */
@Component
public class AppPropertiesProcessor implements InitializingBean {
    private static Logger log = LogManager.getLogger(AppPropertiesProcessor.class);

    private final int HEADER_LEN = 40;

    private static Boolean debugMode = false;

    private static String indexPage = null;
    
    private static String reportingPage = null;

    private static String docRepo = null;

    private static Integer defaultRepo = 1;

    private static Boolean mockEmail = false;

    private static String testUsersBase64 = null;

    private static String whiteListBase64 = null;

    private static String appMode = "DEV";

    private static String VINCIDataManagersEmail = null;
    
    private static String VINCIDARTEmailPrefix = "DART";
    
    private static String VINCIProgramEmail = null;
    

	@Override
    public void afterPropertiesSet() throws Exception {
        // Init DartController
        DartController.setDebugMode(debugMode);
        DartController.setIndexPage(indexPage);
        DartController.setReportingPage(reportingPage);

        // Init Repository
        if (StringUtils.isNotBlank(docRepo)) {
            if (docRepo.endsWith("/") == false) {
                docRepo += "/";
            }
            Repository.FILESTORE_PATH = docRepo;
        }

        if (null != defaultRepo) {
            Repository.defaultRepository = defaultRepo;
        }

        if (StringUtils.isNotBlank(testUsersBase64)) {
            HashMap<String, String> TEST_CREDENTIALS = new HashMap<String, String>();
            byte[] barry = javax.xml.bind.DatatypeConverter.parseBase64Binary(testUsersBase64);
            ByteArrayInputStream bais = new ByteArrayInputStream(barry);
            ObjectInputStream ois = new ObjectInputStream(bais);
            Object obj = ois.readObject();

            String[] sary = (String[]) obj;
            for (int i = 0; (i + 1) < sary.length; i += 2) {
                String uname = sary[i];
                String pwd = sary[i + 1];
                TEST_CREDENTIALS.put(uname, pwd);
            }

            if (!TEST_CREDENTIALS.isEmpty()) {
                UserManagerImpl.setTEST_CREDENTIALS(TEST_CREDENTIALS);
            }
        }

        if (StringUtils.isNotBlank(whiteListBase64)) {
            Set<String> USER_WHITE_LIST = new HashSet<String>();
            byte[] barry = javax.xml.bind.DatatypeConverter.parseBase64Binary(whiteListBase64);
            ByteArrayInputStream bais = new ByteArrayInputStream(barry);
            ObjectInputStream ois = new ObjectInputStream(bais);
            Object obj = ois.readObject();

            String[] sary = (String[]) obj;
            for (String uname : sary) {
                USER_WHITE_LIST.add(uname);
            }

            if (!USER_WHITE_LIST.isEmpty()) {
                UserManagerImpl.setUSER_WHITE_LIST(USER_WHITE_LIST);
            }
        }

        logRunningMode();
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
                .append("appMode", appMode)
                .append("debugMode", debugMode)
                .append("indexPage", indexPage)
                .append("reportingPage", reportingPage)
                .append("defaultRepo", defaultRepo)
                .append("docRepo", docRepo)
                .append("mockEmail", mockEmail)
                .append("testUsersBase64", testUsersBase64)
                .append("whiteListBase64", whiteListBase64)
                .append("VINCIDARTEmailPrefix", VINCIDARTEmailPrefix)
                .toString();
    }

    private void logRunningMode() {
        if (StringUtils.isBlank(appMode)) {
            throw new RuntimeException("Invalid appMode: null");
        }
        StringBuilder msg = new StringBuilder();

        // Header
        String stars = StringUtils.rightPad("", HEADER_LEN, "*");
        msg.append("\n").append(stars).append("\n");
        msg.append("App Properties: ").append(toString()).append("\n");
        msg.append(stars).append("\n");

        log.info(msg.toString());
    }

    public static Boolean getDebugMode() {
        return AppPropertiesProcessor.debugMode;
    }

    public static void setDebugMode(Boolean debugMode) {
        AppPropertiesProcessor.debugMode = debugMode;
    }

    public static String getIndexPage() {
        return AppPropertiesProcessor.indexPage;
    }

    public static void setIndexPage(String indexPage) {
        AppPropertiesProcessor.indexPage = indexPage;
    }
    
    public static String getReportingPage() {
        return AppPropertiesProcessor.reportingPage;
    }

    public static void setReportingPage(String reportingPage) {
        AppPropertiesProcessor.reportingPage = reportingPage;
    }

    public String getDocRepo() {
        return AppPropertiesProcessor.docRepo;
    }

    public static void setDocRepo(String docRepo) {
        AppPropertiesProcessor.docRepo = docRepo;
    }

    public static Integer getDefaultRepo() {
        return AppPropertiesProcessor.defaultRepo;
    }

    public static void setDefaultRepo(Integer defaultRepo) {
        AppPropertiesProcessor.defaultRepo = defaultRepo;
    }

    public static Boolean getMockEmail() {
        return AppPropertiesProcessor.mockEmail;
    }

    public static void setMockEmail(Boolean mockEmail) {
        AppPropertiesProcessor.mockEmail = mockEmail;
    }

    public static String getTestUsersBase64() {
        return AppPropertiesProcessor.testUsersBase64;
    }

    public static void setTestUsersBase64(String testUsersBase64) {
        AppPropertiesProcessor.testUsersBase64 = testUsersBase64;
    }

    public static String getWhiteListBase64() {
        return AppPropertiesProcessor.whiteListBase64;
    }

    public static void setWhiteListBase64(String whiteListBase64) {
        AppPropertiesProcessor.whiteListBase64 = whiteListBase64;
    }

    public static String getAppMode() {
        return AppPropertiesProcessor.appMode;
    }

    public static void setAppMode(String appMode) {
        AppPropertiesProcessor.appMode = appMode;
    }

    public static String getVINCIDataManagersEmail() {
        return VINCIDataManagersEmail;
    }

    public static void setVINCIDataManagersEmail(String VINCIDataManagersEmail) {
        AppPropertiesProcessor.VINCIDataManagersEmail = VINCIDataManagersEmail;
    }
    
    public static String getVINCIDARTEmailPrefix() {
		return AppPropertiesProcessor.VINCIDARTEmailPrefix;
	}

	public static void setVINCIDARTEmailPrefix(String VINCIDARTEmailPrefix) {
		AppPropertiesProcessor.VINCIDARTEmailPrefix = VINCIDARTEmailPrefix;
	}
    
	public static String getVINCIProgramEmail() {
		return VINCIProgramEmail;
	}

	public static void setVINCIProgramEmail(String vINCIProgramEmail) {
		VINCIProgramEmail = vINCIProgramEmail;
	}
	
}
