/*
 * Copyright
 *   2007 axYus - www.axyus.com
 *   2005 C.Marchand - christophe.marchand@axyus.com
 *
 * This file is part of XEMELIOS.
 *
 * XEMELIOS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * XEMELIOS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with XEMELIOS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package fr.gouv.finances.cp.xemelios.ui.admin;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;

import javax.swing.JOptionPane;

import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;

import fr.gouv.finances.cp.utils.PropertiesExpansion;
import fr.gouv.finances.dgfip.xemelios.common.Constants;
import fr.gouv.finances.dgfip.xemelios.common.Scramble;
import java.net.InetAddress;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.NTCredentials;

/**
 *
 * @author  chm
 */
public class PnlProxy extends javax.swing.JPanel implements ParamSaver {
    private static final String URL_TO_REACH = "http://www.xemelios.org/updates33/update.xml";
    private static final Logger logger = Logger.getLogger(PnlProxy.class);
    
    /** Creates new form PnlProxy */
    public PnlProxy() {
        initComponents();
        initValues();
    }
    private void initValues() {
        String proxyServer = System.getProperty(Constants.SYS_PROP_PROXY_SERVER);
        String proxyPort = System.getProperty(Constants.SYS_PROP_PROXY_PORT);
        String proxyUser = System.getProperty(Constants.SYS_PROP_PROXY_USER);
        String proxyPassword = System.getProperty(Constants.SYS_PROP_PROXY_PASSWD);
        String proxyDomain = System.getProperty(Constants.SYS_PROP_PROXY_DOMAIN);
        setValues(proxyServer,proxyPort,proxyUser,proxyPassword,proxyDomain);
    }
    private void setValues(String server, String port, String user, String password, String proxyDomain) {
        if(server!=null) {
            dfProxyServer.setText(server);
            chkUseProxy.setSelected(true);
        } else {
            dfProxyServer.setText("");
            chkUseProxy.setSelected(false);
        }
        enableProxyControls(chkUseProxy.isSelected());
        dfProxyPort.setText(port!=null?port:"");
        if(user!=null) {
            dfProxyUser.setText(user);
            chkAuthenticationRequired.setSelected(true);
        } else {
            dfProxyUser.setText("");
            chkAuthenticationRequired.setSelected(false);
        }
        enableAuthenticationControls(chkAuthenticationRequired.isSelected());
        dfProxyPassword.setText(password!=null?Scramble.unScramblePassword(password):"");
        dfDomainName.setText(proxyDomain!=null?proxyDomain:"");
    }
    private void runTest() {
        String proxyHost = null;
        String proxyPort = null;
        String proxyUser = null;
        String proxyPasswd = null;
        String domainName = null;
        int intProxyPort = 0;
        
        if(dfProxyServer.getText()!=null && dfProxyServer.getText().length()>0) proxyHost = dfProxyServer.getText();
        if(dfProxyPort.getText()!=null && dfProxyPort.getText().length()>0) proxyPort = dfProxyPort.getText();
        if(dfProxyUser.getText()!=null && dfProxyUser.getText().length()>0) proxyUser = dfProxyUser.getText();
        if(dfProxyPassword.getPassword().length>0) proxyPasswd = new String(dfProxyPassword.getPassword());
        if(proxyPort!=null) {
            try {
                intProxyPort = Integer.parseInt(proxyPort);
            } catch(NumberFormatException nfEx) {
                JOptionPane.showMessageDialog(this,proxyPort+" n'est pas un numéro de port valide.","ERREUR",JOptionPane.ERROR_MESSAGE);
                return;
            }
        }
        if(dfDomainName.getText()!=null && dfDomainName.getText().length()>0) domainName = dfDomainName.getText();
        URL url = null;
        try {
            url = new URL(URL_TO_REACH);
        } catch(MalformedURLException muEx) {
            JOptionPane.showMessageDialog(this,"URL not valid : "+URL_TO_REACH,"ERROR",JOptionPane.ERROR_MESSAGE);
            return;
        }
        
// METHOD WITH APACHE COMMONS-HTTPCLIENT
        HttpClient client = new HttpClient();
        HostConfiguration hc = new HostConfiguration();
        if(proxyHost!=null) {
            hc.setProxy(proxyHost,intProxyPort);
            client.setHostConfiguration(hc);
        }
        if(proxyUser!=null) {
            Credentials creds = null;
            if(domainName!=null && domainName.length()>0) {
                String hostName = "127.0.0.1";
                try {
                    InetAddress ip = InetAddress.getByName("127.0.0.1");
                    hostName = ip.getHostName();
                } catch(Exception ex) {
                    logger.error("",ex);
                }
                creds = new NTCredentials(proxyUser, proxyPasswd, hostName, domainName);
            } else {
                creds = new UsernamePasswordCredentials(proxyUser, proxyPasswd);
            }
            client.getState().setProxyCredentials(AuthScope.ANY, creds);
        }
        HttpMethod meth = new GetMethod(URL_TO_REACH);
        int ret = 0;
        try {
            ret = client.executeMethod(meth);
            if(ret>300) {
                // an error occured
                JOptionPane.showMessageDialog(this," "+ret+" : "+meth.getStatusText(),"ERREUR",JOptionPane.ERROR_MESSAGE);
                return;
            } else {
                String resp = meth.getResponseBodyAsString();
                JOptionPane.showMessageDialog(this,"Connexion réussie !","Ok, ça marche...",JOptionPane.INFORMATION_MESSAGE);
            }
        } catch(Throwable t) {
            JOptionPane.showMessageDialog(this,t.getMessage(),t.getClass().getName(),JOptionPane.ERROR_MESSAGE);
        }
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        chkAuthenticationRequired = new javax.swing.JCheckBox();
        chkUseProxy = new javax.swing.JCheckBox();
        pbTest = new javax.swing.JButton();
        lblServer = new javax.swing.JLabel();
        dfProxyServer = new javax.swing.JTextField();
        lblPort = new javax.swing.JLabel();
        dfProxyPort = new javax.swing.JTextField();
        lblUser = new javax.swing.JLabel();
        dfProxyUser = new javax.swing.JTextField();
        lblPassword = new javax.swing.JLabel();
        dfProxyPassword = new javax.swing.JPasswordField();
        pbLoadOld = new javax.swing.JButton();
        lblDomain = new javax.swing.JLabel();
        dfDomainName = new javax.swing.JTextField();

        chkAuthenticationRequired.setText("Mon serveur proxy requiert une authentification");
        chkAuthenticationRequired.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        chkAuthenticationRequired.setMargin(new java.awt.Insets(0, 0, 0, 0));
        chkAuthenticationRequired.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chkAuthenticationRequiredActionPerformed(evt);
            }
        });

        chkUseProxy.setText("J'utilise un serveur proxy pour me connecter à internet");
        chkUseProxy.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        chkUseProxy.setMargin(new java.awt.Insets(0, 0, 0, 0));
        chkUseProxy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chkUseProxyActionPerformed(evt);
            }
        });

        pbTest.setText("Tester");
        pbTest.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pbTestActionPerformed(evt);
            }
        });

        lblServer.setText("Serveur");

        lblPort.setText("Port");

        lblUser.setText("Utilisateur");

        lblPassword.setText("Mot de passe");

        pbLoadOld.setText("Charger l'ancien paramétrage");
        pbLoadOld.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pbLoadOldActionPerformed(evt);
            }
        });

        lblDomain.setText("Domaine Windows");

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, layout.createSequentialGroup()
                        .add(12, 12, 12)
                        .add(pbTest)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 141, Short.MAX_VALUE)
                        .add(pbLoadOld))
                    .add(layout.createSequentialGroup()
                        .addContainerGap()
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                            .add(layout.createSequentialGroup()
                                .add(17, 17, 17)
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(lblUser)
                                    .add(lblPassword)
                                    .add(lblDomain))
                                .add(12, 12, 12)
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(dfProxyUser, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 284, Short.MAX_VALUE)
                                    .add(dfProxyPassword, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 284, Short.MAX_VALUE)
                                    .add(dfDomainName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 284, Short.MAX_VALUE)))
                            .add(org.jdesktop.layout.GroupLayout.LEADING, chkAuthenticationRequired)))
                    .add(org.jdesktop.layout.GroupLayout.LEADING, layout.createSequentialGroup()
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                            .add(org.jdesktop.layout.GroupLayout.LEADING, layout.createSequentialGroup()
                                .add(29, 29, 29)
                                .add(lblServer)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(dfProxyServer, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 265, Short.MAX_VALUE)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(lblPort))
                            .add(org.jdesktop.layout.GroupLayout.LEADING, layout.createSequentialGroup()
                                .addContainerGap()
                                .add(chkUseProxy)))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(dfProxyPort, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 40, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(1, 1, 1)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(chkUseProxy)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(lblServer)
                    .add(dfProxyServer, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(lblPort)
                    .add(dfProxyPort, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(16, 16, 16)
                .add(chkAuthenticationRequired)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(lblUser)
                    .add(dfProxyUser, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(lblPassword)
                    .add(dfProxyPassword, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(lblDomain)
                    .add(dfDomainName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 19, Short.MAX_VALUE)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(pbTest)
                    .add(pbLoadOld))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void pbLoadOldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pbLoadOldActionPerformed
        setValues(System.getProperty("http.proxyHost"),System.getProperty("http.proxyPort"),null,null,null);
    }//GEN-LAST:event_pbLoadOldActionPerformed

    private void pbTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pbTestActionPerformed
        runTest();
    }//GEN-LAST:event_pbTestActionPerformed

    private void chkUseProxyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkUseProxyActionPerformed
        boolean selected = chkUseProxy.isSelected();
        enableProxyControls(selected);
    }//GEN-LAST:event_chkUseProxyActionPerformed

    private void chkAuthenticationRequiredActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkAuthenticationRequiredActionPerformed
        boolean selected = chkAuthenticationRequired.isSelected();
        enableAuthenticationControls(selected);
    }//GEN-LAST:event_chkAuthenticationRequiredActionPerformed
    
    private void enableProxyControls(boolean state) {
        lblServer.setEnabled(state);
        dfProxyServer.setEnabled(state);
        lblPort.setEnabled(state);
        dfProxyPort.setEnabled(state);
        chkAuthenticationRequired.setEnabled(state);
        if(!state) {
            dfProxyServer.setText("");
            dfProxyPort.setText("");
        }
        if(state) enableAuthenticationControls(chkAuthenticationRequired.isSelected());
        else enableAuthenticationControls(false);
    }
    private void enableAuthenticationControls(boolean state) {
        lblUser.setEnabled(state);
        dfProxyUser.setEnabled(state);
        lblPassword.setEnabled(state);
        dfProxyPassword.setEnabled(state);
        lblDomain.setEnabled(state);
        dfDomainName.setEnabled(state);
        if(!state) {
            dfProxyUser.setText("");
            dfProxyPassword.setText("");
            dfDomainName.setText("");
        }
    }

    public void saveConfiguration() {
        // initialize a properties expansion from system properties
        PropertiesExpansion props = new PropertiesExpansion(System.getProperties());
        Properties xemProps = new Properties();
        
        File xemPropsFile = new File(props.replace("${xemelios.prg}/root/xemelios.properties"));
logger.debug("xemPropsFile is "+xemPropsFile.getPath());
        if(!xemPropsFile.exists()) {
        } else {
            try {
                xemProps.load(new FileInputStream(xemPropsFile));

                String proxyHost = null;
                String proxyPort = null;
                String proxyUser = null;
                String proxyPasswd = null;
                String domainName = null;

                if(dfProxyServer.getText()!=null && dfProxyServer.getText().length()>0) proxyHost = dfProxyServer.getText();
                if(dfProxyPort.getText()!=null && dfProxyPort.getText().length()>0) proxyPort = dfProxyPort.getText();
                if(dfProxyUser.getText()!=null && dfProxyUser.getText().length()>0) proxyUser = dfProxyUser.getText();
                if(dfProxyPassword.getPassword().length>0) proxyPasswd = new String(dfProxyPassword.getPassword());
                if(dfDomainName.getText()!=null && dfDomainName.getText().length()>0) domainName = dfDomainName.getText();
                
                if(proxyHost!=null) {
                    xemProps.put(Constants.SYS_PROP_PROXY_SERVER,proxyHost);
                    xemProps.put(Constants.SYS_PROP_PROXY_PORT,proxyPort);
                    System.setProperty(Constants.SYS_PROP_PROXY_SERVER,proxyHost);
                    System.setProperty(Constants.SYS_PROP_PROXY_PORT,proxyPort);
                    if(proxyUser!=null) {
                        xemProps.put(Constants.SYS_PROP_PROXY_USER,proxyUser);
                        xemProps.put(Constants.SYS_PROP_PROXY_PASSWD,Scramble.scramblePassword(proxyPasswd));
                        System.setProperty(Constants.SYS_PROP_PROXY_USER,proxyUser);
                        System.setProperty(Constants.SYS_PROP_PROXY_PASSWD,Scramble.scramblePassword(proxyPasswd));
                    } else {
                        xemProps.remove(Constants.SYS_PROP_PROXY_USER);
                        xemProps.remove(Constants.SYS_PROP_PROXY_PASSWD);
                        System.getProperties().remove(Constants.SYS_PROP_PROXY_USER);
                        System.getProperties().remove(Constants.SYS_PROP_PROXY_PASSWD);
                    }
                    if(domainName!=null) {
                        xemProps.put(Constants.SYS_PROP_PROXY_DOMAIN,domainName);
                        System.setProperty(Constants.SYS_PROP_PROXY_DOMAIN,domainName);
                    } else {
                        xemProps.remove(Constants.SYS_PROP_PROXY_DOMAIN);
                        System.getProperties().remove(Constants.SYS_PROP_PROXY_DOMAIN);
                    }
                } else {
                    xemProps.remove(Constants.SYS_PROP_PROXY_SERVER);
                    xemProps.remove(Constants.SYS_PROP_PROXY_PORT);
                    xemProps.remove(Constants.SYS_PROP_PROXY_USER);
                    xemProps.remove(Constants.SYS_PROP_PROXY_PASSWD);
                    System.getProperties().remove(Constants.SYS_PROP_PROXY_SERVER);
                    System.getProperties().remove(Constants.SYS_PROP_PROXY_PORT);
                    System.getProperties().remove(Constants.SYS_PROP_PROXY_USER);
                    System.getProperties().remove(Constants.SYS_PROP_PROXY_PASSWD);
                }
                xemProps.store(new FileOutputStream(xemPropsFile),"");
            } catch(IOException ioEx) {
                logger.error("while saving proxy configuration: ",ioEx);
            }
        }

    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox chkAuthenticationRequired;
    private javax.swing.JCheckBox chkUseProxy;
    private javax.swing.JTextField dfDomainName;
    private javax.swing.JPasswordField dfProxyPassword;
    private javax.swing.JTextField dfProxyPort;
    private javax.swing.JTextField dfProxyServer;
    private javax.swing.JTextField dfProxyUser;
    private javax.swing.JLabel lblDomain;
    private javax.swing.JLabel lblPassword;
    private javax.swing.JLabel lblPort;
    private javax.swing.JLabel lblServer;
    private javax.swing.JLabel lblUser;
    private javax.swing.JButton pbLoadOld;
    private javax.swing.JButton pbTest;
    // End of variables declaration//GEN-END:variables
    
}
