/** BEGIN COPYRIGHT BLOCK
 * Copyright (C) 2001 Sun Microsystems, Inc.  Used by permission.
 * Copyright (C) 2005 Red Hat, Inc.
 * All rights reserved.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 * END COPYRIGHT BLOCK **/
package com.netscape.management.admserv.panel;

import java.util.*;
import java.net.*;
import java.text.MessageFormat;
import com.netscape.management.client.util.*;
import com.netscape.management.client.comm.HttpChannel;
import com.netscape.management.client.console.ConsoleInfo;
import com.netscape.management.admserv.config.*;

/**
  *
  * @version 0.1 11/28/97
  * @author miodrag@netscape.com
  */
public abstract class CGIDataModel implements IConfigDataModel {

    static ResourceSet _resource;
    static String _i18nProgressLoading, _i18nProgressSaving,
    _i18nLoadFailed, _i18nSaveFailed;

    static {
        _resource = new ResourceSet("com.netscape.management.admserv.panel.panel");
        _i18nProgressLoading = _resource.getString("adminop","ProgressLoading");
        _i18nProgressSaving = _resource.getString("adminop","ProgressSaving");
        _i18nLoadFailed = _resource.getString("adminop","LoadFailed");
        _i18nSaveFailed = _resource.getString("adminop","SaveFailed");
    }

    protected Hashtable _data, _origData;
    protected ConsoleInfo _consoleInfo;
    protected boolean _loaded, _saved, _modified;
    protected String _taskURL;
    protected String _adminURL;

    protected java.awt.Component _dialogParent; // for info messages

    public CGIDataModel(ConsoleInfo consoleInfo, String taskURL) {
        _consoleInfo = consoleInfo;
        _taskURL = taskURL;
        _adminURL = _consoleInfo.getAdminURL() + _taskURL;
    }

    static public String getServerName(ConsoleInfo ci) {
        String server = (String) ci.get("SERVER_NAME");
        if (server == null) {
            Debug.println("CGIDataModel.getServerName: SERVER_NAME not found in console info");
            return "unknown";
        }
        return server;
    }

    public String getModelName() {
        return getServerName(_consoleInfo);
    }


    public ConsoleInfo getConsoleInfo() {
        return _consoleInfo;
    }

    public Enumeration getAttributes() {
        return _data.keys();
    }

    /**
      * Implements IConfigDataModel.isLoaded()
     */
    public boolean isLoaded() {
        return _loaded;
    }

    /**
      * Implements IConfigDataModel.load()
     */
    public void load() throws RemoteRequestException {
        if (ActionMonitorPanel.getActiveInstance() != null) {
            MessageFormat msg = new MessageFormat(_i18nProgressLoading);
            Object[] msgArgs = { "" }; //{ getModelName() };
            ActionMonitorPanel.getActiveInstance().setStatusText(
                    msg.format(msgArgs));
        }
        _data = getConfiguration(_adminURL, getCGIParamsForGetOp());
        _loaded = ! _data.isEmpty();
        if (!_loaded) {
            throw new RemoteRequestException(_adminURL, _i18nLoadFailed);
        }
        _origData = cloneStringHashtable(_data, null);
    }

    /**
      * Implements IConfigDataModel.isLoaded()
     */
    public boolean isModified() {
        //Debug.println(getClass().getName() + " modified=" + _modified);
        return _modified;
    }


    /**
      * Implements IConfigDataModel.save()
     */
    public void save() throws RemoteRequestException {
        if (ActionMonitorPanel.getActiveInstance() != null) {
            MessageFormat msg = new MessageFormat(_i18nProgressSaving);
            Object[] msgArgs = { getModelName()};
            ActionMonitorPanel.getActiveInstance().setStatusText(
                    msg.format(msgArgs));
        }

        try {
            setConfiguration(_adminURL, getCGIParamsForSetOp());
            if (!_saved) {
                throw new RemoteRequestException(_adminURL,
                        _i18nSaveFailed);
            }
        } catch (RemoteRequestException e) {
            _data.clear();
            _data = cloneStringHashtable(_origData, null);
            throw e;
        }
        _origData.clear();
        _origData = cloneStringHashtable(_data, null);
        _modified = false;
    }

    /**
      * Implements IConfigDataModel.getAttribute()
     */
    public String getAttribute(String attr) {
        return (String)_data.get(attr);
    }

    /**
      * Implements IConfigDataModel.setAttribute()
     */

    public void setAttribute(String attr,
            String val) throws ValidationException {
        String curVal = getAttribute(attr);
        if (!_modified) {
            _modified = (val == null) ? (curVal != null) :
                    !(val.equals(curVal));
        }
        //Debug.println(attr + " curVal="+curVal+" val="+val+"modified="+_modified);
        _data.put(attr, val);
    }


    public String toURLformat(Hashtable args) {
        String p = "";
        Enumeration e = args.keys();
        while (e.hasMoreElements()) {
            String name = (String) e.nextElement();
            String value = (String) args.get(name);

            p += name + "=" + URLByteEncoder.encodeUTF8(value) +
                    (e.hasMoreElements() ? "&":"");
        }
        return p;
    }

    public static Hashtable cloneStringHashtable(Hashtable tbl,
            String renamePrefix) {
        Hashtable out = new Hashtable();
        for (Enumeration e = tbl.keys(); e.hasMoreElements();) {
            String key = (String) e.nextElement();
            String val = (String) tbl.get(key);

            if (renamePrefix == null) {
                out.put(new String(key), new String(val));
            } else {
                out.put(renamePrefix + key, new String(val));
            }
        }
        return out;
    }


    public static Vector commaStringToVector(String s) {
        Vector v = new Vector();
        if (s != null) {
            StringTokenizer st = new StringTokenizer(s, ",");
            while (st.hasMoreTokens()) {
                v.addElement(st.nextToken());
            }
        }
        return v;
    }

    public static String vectorToCommaString(Vector v) {
        String s = "";
        Enumeration e = v.elements();
        while (e.hasMoreElements()) {
            s = s + e.nextElement();
            if (e.hasMoreElements())
                s = s + ",";
        }
        return s;
    }

    public java.awt.Component getDialogParent() {
        return _dialogParent;
    }

    public void setDialogParent (java.awt.Component comp) {
        _dialogParent = comp;
    }

    /**
      * CGI arguments used in getConfiguration()
     */
    public abstract String getCGIParamsForGetOp();

    /**
     * CGI arguments used in setConfiguration()
    */
    public abstract String getCGIParamsForSetOp();

    protected Hashtable getConfiguration(String adminURL,
            String args) throws RemoteRequestException {
        AdmTask task = null;
        try {
            task = new AdmTask(new URL(adminURL),
                    _consoleInfo.getAuthenticationDN(),
                    _consoleInfo.getAuthenticationPassword());
        } catch (MalformedURLException e) {
            Debug.println("CGIDataModel.getConfiguration "+e);
            throw new RemoteRequestException(e);
        }

        //task.trace();
        if (args != null) {
            //task.setArguments(HttpChannel._encode(args));
            task.setArguments(args);
        }
        task.exec();

        int status = task.getStatus();
        _loaded = (status == 0);
        Debug.println("CGIDataModel.getConfiguration(): called URL " +
                      adminURL + " "+status);

        AdminOperation.processAdmTaskStatus(adminURL, task, _consoleInfo);

        if (task != null) {
            //Debug.printHashtable("config", task.getResult());
            return task.getResult();
        }

        return new Hashtable();

    }

    protected void setConfiguration(String adminURL,
            String args) throws RemoteRequestException {
        AdmTask task = null;
        try {
            task = new AdmTask(new URL(adminURL),
                    _consoleInfo.getAuthenticationDN(),
                    _consoleInfo.getAuthenticationPassword());
        } catch (MalformedURLException e) {
            Debug.println("CGIDataModel.setConfiguration "+e);
            throw new RemoteRequestException(e);
        }

        //task.trace();
        if (args != null) {
            task.setArguments(args);
        }
        task.exec();

        int status = task.getStatus();
        Debug.println(adminURL + " "+status);
        _saved = (status == 0);
        AdminOperation.processAdmTaskStatus(adminURL, task, _consoleInfo);
    }
}
