/*
 * Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

/**
 * AdminBaseDevTest is a base class for administration CLI dev tests.
 *
 * @author Byron Nevins
 * @author tmueller
 */
package admin;

import com.sun.appserv.test.BaseDevTest;
import java.io.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.SortedSet;
import java.util.TreeSet;
import static admin.Constants.*;
import javax.xml.namespace.QName;

public abstract class AdminBaseDevTest extends BaseDevTest implements Runnable {

    static enum PasswordType {

        SSH_PASS, KEY_PASS, ALIAS_PASS
    };

    @Override
       protected final void writeFailure() {
        // writes to stdout
        super.writeFailure();
        AsadminReturn ret = getLastAsadminReturn();

        // put the information right into the CLI log.  Makes it much easier
        // to figure out failures.

        if (ret != null) {
           TestUtils.writeErrorToDebugLog(ret);
        }

        // byron nevins, June 2013.  We need an easy way to see if there were
        // ANY errors at all
        TestUtils.setErrorFile();
    }

    protected AdminBaseDevTest() {
        boolean verbose = false;
        try {
            verbose = Boolean.parseBoolean(System.getProperty("verbose"));
        }
        catch (Exception e) {
        }

        setVerbose(verbose);
        if (!verbose) {
            System.out.println("#####  Non-Verbose: Only Failures Are Printed #####");
        }
    }

    // Byron Says:
    // let's make this an abstract method someday when we have time to change
    // all the test classes
    public void subrun() {
        // all subclasses someday should have this method which is called by run()
        // the subclass should call run() which will help with housekeeping.
        // I'm not enforcing yet because I don't have time to change all the
        // classes!  10/12/11
        // do nothing.
    }

    @Override
    public File getGlassFishHome() {
        return TestEnv.getGlassFishHome();
    }

    // Allow old-style and new-style simultaneously.  But prefer the latter.
    @Override
    public File getDASDomainDir() {
        return getDASDomainDir("domain1");
    }

    File getDASDomainDir(String domainName) {
        File f = null;

        if (isHadas())
            f = new File(DOMAINS_DIR, domainName + "/server");
        else
            f = new File(DOMAINS_DIR, domainName);

        if (!f.exists())
            report(false, "Domain Directory does not exist: " + f);

        return f;
    }

     @Override
    public File getDASDomainXML() {
         return TestEnv.getDomainXml();
    }

    File getDASDomainXML(String domainName) {
         return TestEnv.getDomainXml(domainName);
    }

    @Override
    public Object evalXPath(String expr, QName ret) {
        return evalXPath(expr, getDASDomainXML(), ret);
    }

    @Override
    public final void run() {
        System.out.println(getTestDescription());
        System.out.println(getTestName());
        subrun();
        stat.printSummary();
    }

    @Override
    public String getTestName() {
        return this.getClass().getName();
    }

    // convenience method
    static boolean isHadas() {
        return TestEnv.isHadas();
    }

    public static File getLogFile(File installDir, String domainName) {
        if (isHadas()) {
            return new File(installDir, "domains/" + domainName + "/server/logs/server.log");
        }
        else {
            return new File(installDir, "domains/" + domainName + "/logs/server.log");
        }
    }

    public void report(boolean success, String name) {
        // WBN ==> sometimes I like it in this order!
        report(name, success);
    }

    @Override
    public void report(String name, boolean success) {
        // bnevins june 6 2010

        // crazy base class uses a Map to store these reports.  If you use
        // the same name > 1 time they are ignored and thrown away!!!
        // I went with this outrageous kludge because (1) it is just tests
        // and (2) there are tens of thousands of other files in this harness!!!

        // another issue is hacking off strings after a space.  Makes no sense to me!!
        if (!success) {
            int x = 5;  // a place to hang a breakpoint when debugging!!
        }
        writeTimestamp(name, success);
        if (name.length() > MAX_LENGTH - 3) {
            name = name.substring(0, MAX_LENGTH - 3);
        }
        String name2 = name.replace(' ', '_');
        if (!name2.equals(name)) {
            name = name2;   // don't foul logic below!
        }

        int i = 0;

        while (reportNames.add(name2) == false) {
            name2 = name + i++;
        }

        if (!name2.equals(name)) {
            write("Duplicate name found (" + name
                    + ") and replaced with: " + name2);
        }

        int numpads = 60 - name2.length();

        if (numpads > 0) {
            name2 += DASHES.substring(0, numpads);
        }

        super.report(name2, success);

        if (!success) {
            writeFailure();
        }
    }

    @Override
    public void report(String step, AsadminReturn ret) {
        report(step, ret.returnValue);
    }

    protected void startDomain(String domainname) {
        report(getTestName() + "-start-domain" + startstops++,
                asadmin("start-domain", domainname));
    }

    protected void startDomain() {
        report(getTestName() + "-start-def-domain" + startstops++,
                asadmin("start-domain"));
    }

    protected void startDomainDebug() {
        report(getTestName() + "-start-def-domain" + startstops++,
                asadmin("start-domain", "--debug"));
    }

    protected void stopDomain(String domainname) {
        report(getTestName() + "-stop-domain" + startstops++,
                asadmin("stop-domain", domainname));
    }

    protected void stopDomain() {
        report(getTestName() + "-stop-def-domain" + startstops++,
                asadmin("stop-domain"));
    }

    protected final boolean verifyNoClusters() {
        AsadminReturn ret = asadminWithOutput("list-clusters");
        String s = (ret.out == null) ? "" : ret.out.trim();

        s = s.toLowerCase();
        return s.endsWith("list-clusters") || s.indexOf("nothing to list") >= 0;
    }

    protected final boolean verifyNoInstances() {
        AsadminReturn ret = asadminWithOutput("list-instances");
        String s = (ret.out == null) ? "" : ret.out.trim();
        return s.toLowerCase().indexOf("nothing to list") >= 0;
    }

    /*
     * Returns true if String b contains String a.
     */
    protected static boolean matchString(String a, String b) {
        return b.indexOf(a) != -1;
    }

    static String getURL(String urlstr) {
        try {
            URL u = new URL(urlstr);
            URLConnection urlc = u.openConnection();
            BufferedReader ir = new BufferedReader(new InputStreamReader(urlc.getInputStream(),
                    "ISO-8859-1"));
            StringWriter ow = new StringWriter();
            String line;
            while ((line = ir.readLine()) != null) {
                ow.write(line);
                ow.write("\n");
            }
            ir.close();
            ow.close();
            return ow.getBuffer().toString();
        }
        catch (IOException ex) {
            printf("unable to fetch URL:" + urlstr + ", reason: " + ex.getMessage());
            return "";
        }
    }

    static void printf(String fmt, Object... args) {
        if (DEBUG) {
            System.out.printf("**** DEBUG MESSAGE ****  " + fmt + "\n", args);
        }
    }
    private final SortedSet<String> reportNames = new TreeSet<String>();
    private int startstops = 0;
    protected final static boolean DEBUG;
    protected final static boolean isHudson = Boolean.parseBoolean(System.getenv("HUDSON"));

    static {
        String name = System.getProperty("user.name");

        if (name != null && name.equals("bnevins")) {
            DEBUG = true;
        }
        else if (isHudson) {
            DEBUG = true;
        }
        else if (Boolean.parseBoolean(System.getenv("AS_DEBUG"))) {
            DEBUG = true;
        }
        else {
            DEBUG = false;
        }
    }

    String generateInstanceName() {
        String s = "" + System.currentTimeMillis();
        s = s.substring(4, 10);
        return "in_" + s;
    }

    String generateClusterName() {
        String s = "" + System.currentTimeMillis();
        s = s.substring(4, 10);
        return "cl_" + s;
    }

    String get(String what) {
        // note that the returned string is full of junk -- namely the HUGE asadmin
        // command is prepended to the output.
        // the "get" key will appear TWICE!!!!!!  Once for the echo of the command itself
        // and once for the output of the command.

        AsadminReturn ret = asadminWithOutput("get", what);
        if (!ret.returnValue) {
            return null;
        }

        int index = ret.outAndErr.lastIndexOf(what);
        int len = ret.outAndErr.length();

        if (index < 0 || len - index <= 2) {
            return null;
        }

        // e.g. "asadmin blah foo=xyz  len==20, index==13,  start at index=17
        // which is index+lenofget-string+1
        int valueIndex = index + what.length() + 1;
        return ret.outAndErr.substring(index + what.length() + 1).trim();
    }

    public final boolean doesGetMatch(String what, String match) {
        String ret = get(what);

        if (!ok(match) && !ok(ret)) {
            return true;
        }

        if (!ok(match) || !ok(ret)) {
            return false;
        }

        return (match.equals(ret));
    }

    /**
     * returns true if there is anything in the config that matches. returns
     * false if there is no such thing
     *
     * @param what
     * @return
     */
    public final boolean doesGetMatch(String what) {
        AsadminReturn ret = asadminWithOutput("get", what);

        if (!ret.returnValue) {
            return false;
        }

        if (ret.err != null && ret.err.length() > 1) {
            return false;
        }

        return ret.out != null && ret.out.indexOf("=") >= 0;
    }

    public static void runFakeServerDaemon(int port) {
        Thread t = new Thread(new FakeServer(port), "FakeServerListeningOn: " + port);
        t.setDaemon(true);
        t.start();
    }

    /**
     *
     * typical output as og 6/6/10
     * C:\glassfishv3\glassfish\nodeagents\vaio>asadmin list-instances in_879669
     * not running i20 running
     */
    public boolean isInstanceRunning(String iname) {
        AsadminReturn ret = asadminWithOutput("list-instances");
        String[] lines = ret.out.split("[\r\n]");

        // beware!  The echo'd command can have a pathwith the instance name embedded,
        // innocently in it.  THis happened on a Hudson build which had a directory named
        // makati1 in it!!
        // So now we throw away the echo'd command line if we see it (just in case we turn
        // echoing off later)

        for (String line : lines) {
            if (line.indexOf("list-instances") >= 0) {
                continue;
            }

            if (line.indexOf(iname) >= 0) {
                printf("Line from list-instances = " + line);
                return line.indexOf("  running") >= 0;
            }
        }
        return false;
    }

    public boolean isClusterRunning(String cname) {
        AsadminReturn ret = asadminWithOutput("list-clusters");
        String[] lines = ret.out.split("[\r\n]");

        for (String line : lines) {
            if (line.indexOf(cname) >= 0) {
                printf("Line from list-clusters = " + line);
                return line.indexOf(cname + " running") >= 0;
            }
        }
        return false;
    }

    public boolean isClusterPartiallyRunning(String cname) {
        AsadminReturn ret = asadminWithOutput("list-clusters");
        String[] lines = ret.out.split("[\r\n]");

        for (String line : lines) {
            if (line.indexOf(cname) >= 0) {
                printf("Line from list-clusters = " + line);
                return line.indexOf(cname + " partially running") >= 0;
            }
        }
        return false;
    }

    /*
     * Delete the directories for a local node (since delete-node-* doesn't do
     * this
     */
    public boolean deleteNodeDirectory(String node) {
        return deleteDirectory(new File(new File(getGlassFishHome(), "nodes"), node));
    }

    public boolean deleteDirectory(File path) {
        if (path.exists()) {
            File[] files = path.listFiles();
            for (File f : files) {
                if (f.isDirectory()) {
                    deleteDirectory(f);
                }
                else {
                    f.delete();
                }
            }
        }
        return (path.delete());
    }

    /**
     * Add a password to the asadmin password file used by the test.
     *
     * @param value Password to use
     * @param passType SSH_PASS if you are setting ssh password. KEY_PASS if you
     * are setting encryption key
     */
    void addPassword(String value, PasswordType passType) {
        BufferedWriter out = null;

        if (value == null) {
            value = "";
        }
        try {
            final File f = new File(pFile);
            out = new BufferedWriter(new FileWriter(f, true));
            out.newLine();
            switch (passType) {
                case SSH_PASS:
                    out.write("AS_ADMIN_SSHPASSWORD=" + value);
                    break;
                case KEY_PASS:
                    out.write("AS_ADMIN_SSHKEYPASSPHRASE=" + value);
                    break;
                case ALIAS_PASS:
                    out.write("AS_ADMIN_ALIASPASSWORD=" + value);
                    break;
                default:
                //do nothing
            }
        }
        catch (IOException ioe) {
            //ignore
        }
        finally {
            try {
                if (out != null) {
                    out.flush();
                    out.close();
                }
            }
            catch (final Exception ignore) {
            }
        }

        return;
    }

    /**
     * Remove SSH related passwords from the asadmin password file id == "SSH"
     * or "DCOM"
     */
    void removePasswords(String id) {
        final File f = new File(pFile);
        final File tempFile = new File(tmpFile);

        BufferedReader reader = null;
        BufferedWriter writer = null;

        try {
            writer = new BufferedWriter(new FileWriter(tempFile));
            reader = new BufferedReader(new FileReader(f));

            String currentLine;

            while ((currentLine = reader.readLine()) != null && !currentLine.trim().isEmpty()) {
                if (currentLine.trim().startsWith("AS_ADMIN_" + id)) {
                    continue;
                }
                writer.write(currentLine);
                writer.newLine();
            }

            reader.close();
            writer.close();

            //On Windows, rename will fail if destination file already exists
            if (!f.delete()) {
                System.out.println("Failed to delete original file");
            }

            if (!tempFile.renameTo(f)) {
                System.out.println("Failed to restore password file.");
            }
        }
        catch (IOException ioe) {
            //ignore
        }
        finally {
            try {
                if (reader != null) {
                    reader.close();
                }
                if (writer != null) {
                    writer.close();
                }
            }
            catch (final Exception ignore) {
            }
        }

        return;
    }

    final boolean ok(String s) {
        return s != null && s.length() > 0;
    }

    // bnevins - horribly inefficient but we are guaranteeing to see contents when exited abruptly.
    // It can't possibly take all that long for a few thousand calss - right?
    // If a problem it can be tuned easily.
    // this will give a rough idea of the time spent for every report call
    private static void writeTimestamp(String s, boolean b) {
        BufferedWriter out = null;
        long prevTime = lastReportTime;
        lastReportTime = System.currentTimeMillis();

        long elapsed = prevTime == 0 ? 0 : lastReportTime - prevTime;

        try {
            out = new BufferedWriter(new FileWriter(TIMESTAMP_FILE, true));
            out.write("" + elapsed + "ms " + b + "  [" + s + "]");
        }
        catch (IOException e) {
            // It is just a debug file.
        }
        finally {
            if (out != null) {
                try {
                    out.write("\n");
                    out.close();
                }
                catch (Exception e) {
                    // ignore
                }
            }
        }
    }
    private static final File TIMESTAMP_FILE = new File("timestamps.out").getAbsoluteFile();
    private final File GF_HOME = getGlassFishHome();
    private final File DOMAINS_DIR = new File(GF_HOME, "domains");
    private static long lastReportTime = 0;
    private static final int MAX_LENGTH = 101;
    private static final String DASHES =
            "------------------------------------------------------------------------------------------------------------------------------";
}
