/**
 * ZipSnap 2.1
 * Copyright 2007 Zach Scrivena
 * 2007-08-26
 * zachscrivena@gmail.com
 * http://zipsnap.sourceforge.net/
 *
 * ZipSnap is a simple command-line incremental backup tool for directories.
 *
 * TERMS AND CONDITIONS:
 * 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, either version 3 of the License, or
 * (at your option) any later version.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */

package zipsnap;

import java.util.Scanner;


/**
 * Simple class for handling errors and warnings.
 */
public class ErrorWarningHandler
{
    /** counter for number of errors */
    private static int numErrors = 0;

    /** counter for number of warnings */
    private static int numWarnings = 0;

    /** pause when a warning is issued if true; does not pause otherwise */
    private static boolean pauseOnWarning = true;

    /** default status code to be returned when calling System.exit() */
    private static final int defaultExitCode = 1;


    /**
    * Set pause-on-warning mode.
    *
    * @param pauseOnWarning
    *     Pause-on-warning mode: the handler pauses on warnings if true,
    *     and does not pause otherwise
    */
    public static void setPauseOnWarning(
            final boolean pauseOnWarning)
    {
        ErrorWarningHandler.pauseOnWarning = pauseOnWarning;
    }


    /**
    * Return the number of errors encountered so far.
    *
    * @return
    *     Number of errors encountered so far
    */
    public static int getNumErrors()
    {
        return numErrors;
    }


    /**
    * Return the number of warnings encountered so far.
    *
    * @return
    *     Number of warnings encountered so far
    */
    public static int getNumWarnings()
    {
        return numWarnings;
    }


    /**
    * Print a warning message and pause.
    *
    * @param warningMessage
    *     Warning message to be printed on issuing the warning
    */
    public static void reportWarning(
            final Object warningMessage)
    {
        numWarnings++;

        System.err.print("\nWARNING: " + warningMessage + "\n");
        System.err.flush();

        if (!pauseOnWarning) return;

        System.err.print("Press ENTER to continue...");
        System.err.flush();

        try
        {
            (new Scanner(System.in)).nextLine();
        }
        catch (Exception e)
        {
            reportErrorAndExit("(FATAL) Cannot read from keyboard.\n" +
                    getExceptionMessage(e));
        }
    }


    /**
    * Print an error message and terminate program with specified exit code.
    *
    * @param errorMessage
    *     Error message to be printed on issuing the error
    * @param exitCode
    *     Exit status code for program termination
    */
    public static void reportErrorAndExit(
            final Object errorMessage,
            final int exitCode)
    {
        numErrors++;

        System.err.print("\nERROR: " + errorMessage +
                "\nProgram aborted.\n\n");
        System.err.flush();

        System.exit(exitCode);
    }


    /**
    * Print an error message and terminate program with default exit code.
    *
    * @param errorMessage
    *     Error message to be printed on issuing the error
    */
    public static void reportErrorAndExit(
            final Object errorMessage)
    {
        reportErrorAndExit(errorMessage, defaultExitCode);
    }


    /**
    * Get custom exception message string for the given exception.
    * Message contains the exception class name, error description string,
    * and stack trace.
    *
    * @param e
    *     Exception for which to generate the custom message string
    */
    public static String getExceptionMessage(
            final Exception e)
    {
        final StackTraceElement[] stackTrace = e.getStackTrace();
        final StringBuilder a = new StringBuilder();

        a.append("\nJava exception information (" + e.getClass() +
                "):\n\"" + e.getMessage() + "\"");

        for (int i = 0; i < stackTrace.length; i++)
        {
            a.append("\n  at ");
            a.append(stackTrace[i]);
        }

        a.append('\n');
        return a.toString();
    }
}