/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* IBM UrbanCode Deploy
* IBM UrbanCode Release
* IBM AnthillPro
* (c) Copyright IBM Corporation 2002, 2017. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/
package com.urbancode.air.plugin.websphereliberty;
import com.urbancode.air.CommandHelper;
import java.io.InputStream;
import java.io.OutputStream;

/*
 * 1.  This class deals with updating httpd.conf file.
 * 2.  This class expects that "WebSphere Plugins" is installed.
 * 3. Address the OS differences
 */
public class WebserverHelper {
    def webserverHome;
    def httpdConf;
    def pluginCfgXml;
    def wasPluginsHome;
    def wasPluginSo;
    def arch;
    def ihsv;
    def libfile;
    def wasModule;

    // constructor, also checks the input params
    protected WebserverHelper( String webserver,
                               String pluginConfig,
                               String wasPlugins,
                               String wlpUserDir=null) {

        webserverHome = webserver;
        // check if webserver is installed
        if ( !(new File(webserverHome).isDirectory()) ) {
               throw new RuntimeException("\"" + webserverHome + "\" does not exist! " );
        }

        // check for the webs server configuration file presence
        httpdConf = webserverHome + "/conf/httpd.conf";
        if ( !(new File(httpdConf).isFile()) ) {
            throw new RuntimeException("\"" + webserverHome + "\" /conf/httpd.conf file does not exist!");
        }
        println "httd conf: " + httpdConf;

        // how to check if the plugin-cfg.xml is a valid file?
        pluginCfgXml = pluginConfig;
        if (!(new File(pluginCfgXml).isFile()) ) {
            throw new RuntimeException("\"" + pluginCfgXml + "\" file does not exist!");
        }

        // check if mergePluginHome directory has write permissions
        File configDir = new File (webserverHome +"/conf");
        if ( ! configDir.canWrite() ){
            throw new RuntimeException("The directory to place merged-plugin-config file is NOT writeable.");
        }
        configDir = null;

        // 32 or 64-bit
        if ( System.properties['os.arch'].contains('64') ) {
            arch = '64bits';
        }
        else {
            arch = '32bits';
        }

        /*
         * Get web server version to determine which was module and shared library to use
         */
        ihsv = new File(webserver + '/version.signature').text;
        println "IHS version: " + ihsv;

        if (ihsv.contains("IBM HTTP Server 9")) {
            wasModule = "was_ap24_module";
            libfile   = 'mod_was_ap24_http.so';
        }
        else {
            wasModule = "was_ap22_module";
            libfile    = "mod_was_ap22_http.so";
        }

        // wasPlugin is being set IHS V9
        wasPluginsHome = wasPlugins;
        if( !(new File(wasPluginsHome).isDirectory()) ) {
            throw new RuntimeException ("\"" + wasPluginsHome + "\" not found on the system!");
        }

        wasPluginSo = wasPlugins + "/bin/" + arch + "/" + libfile;
        if( !(new File(wasPluginSo).isFile())) {
            throw new RuntimeException ("\"" + wasPluginSo + "\" shared library not found!");
        }
        println "WAS Shared library: " + wasPluginSo;

    } // end of constructor

    // TODO: Windows OS yet to be handled.
    protected void modifyHttpdConf () {

        // httpdConfFile is httpd.conf if present, i.e. IHS/apache installed
        FileInputStream  fis = new FileInputStream(httpdConf);
        FileOutputStream fos = new FileOutputStream("tempfile.conf");

        BufferedReader br = new BufferedReader(new InputStreamReader(fis));
        OutputStreamWriter ow = new OutputStreamWriter(fos);

        String line;
        String lineSep = System.getProperty("line.separator");

        // update httpd.conf
        while ( (line = br.readLine()) != null ){
            println(line);

            try {
                if(line.charAt(0) == "#") {
                    ow.write(line + lineSep);
                    continue;
                }
                else { // comment out any existing
                    if(line.contains("LoadModule") && line.contains(wasModule)) {
                        ow.write("# " + line + lineSep);
                        continue;
                    }
                    else if(line.contains("WebSpherePluginConfig")) {
                        ow.write("# " + line + lineSep);
                        continue;
                    }
                    else {
                        ow.write(line + lineSep);
                    }
                }
            } catch ( RuntimeException re) {
                // blank line was read
            }
        } // end of while

        // now that any previous occurrences have been commented out.
        // let's update httpd.conf
        ow.write("LoadModule " + wasModule + " " + wasPluginSo + lineSep);
        ow.write("WebSpherePluginConfig " + webserverHome + "/conf/" + pluginCfgXml + lineSep);

        // close streams/files
        br.close();
        ow.close();

        replaceOldConfigFile("tempfile.conf", httpdConf );
        println("\n\n Done changing the config file.")
    } // end of propagatePluginConfig

    protected boolean fileContains(java.io.File file, java.lang.String str) {
        boolean flag = false;
        String searchStr = file.filterLine { line ->
            line.contains(str)
        }
        if (searchStr != null && searchStr.length() > 0 ) flag = true;
        return flag;
    }

    protected boolean backupHttpdConf() {
        def source      = new File(httpdConf);
        def destination = new File(httpdConf+'.'+ new Date().format
            ('yyyy-MM-dd-HHmm', TimeZone.getTimeZone('UTC')));
        destination.write(source.text);

        if (!destination.isFile()) {
            throw new RuntimeException("The original httpd.conf file could not be backed up.")
        }
        return true;
    }

    protected boolean replaceOldConfigFile(srcFile, destFile) {
        def src = new File(srcFile);
        def dest = new File(destFile);
        dest.write(src.text);

        if (!dest.isFile()) {
            throw new RuntimeException("The existing httpd.conf file could not be replaced. ")
        }

        return true;
    }

    // After successful modification of the httpd.conf, copy the merged config xml to its expected location
    protected boolean copyPluginConfig() {
        def sourcePlugin = new File( pluginCfgXml);
        def targetPlugin = new File (webserverHome + "/conf/" + pluginCfgXml);

        targetPlugin.write(sourcePlugin.text);

        if (!targetPlugin.isFile()) {
            throw new RuntimeException("The merged plugin-config could not be placed in " + webserverHome + "/conf");
        }
        return true;
    }

}
