package org.clapper.util.misc;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * Base class for classes that want to access and display version information
 * that's stored in a resource bundle generated by
 * {@link BuildInfo#makeBuildInfoBundle BuildInfo.makeBuildInfoBundle()}
 * as well as a static resource bundle containing non-build related strings.
 */
public abstract class VersionBase
{
    /*----------------------------------------------------------------------*\
                               Private Constants
    \*----------------------------------------------------------------------*/

    /*----------------------------------------------------------------------*\
                             Private Instance Data
    \*----------------------------------------------------------------------*/

    /*----------------------------------------------------------------------*\
                                   Constructor
    \*----------------------------------------------------------------------*/

    /**
     * Creates a new instance of <tt>VersionBase</tt>
     */
    protected VersionBase()
    {
    }

    /*----------------------------------------------------------------------*\
                                Public Methods
    \*----------------------------------------------------------------------*/

    /**
     * Get the version number.
     *
     * @return the version number
     */
    public String getVersion()
    {
        return BundleUtil.getString(getVersionBundleName(),
                                    getVersionKey(),
                                    "?");
    }

    /**
     * Get the copyright string.
     *
     * @return the copyright string.
     */
    public String getCopyright()
    {
        return BundleUtil.getString(getVersionBundleName(),
                                    getCopyrightKey(),
                                    "?");
    }

    /**
     * Get the application name.
     *
     * @return the application name
     */
    public String getApplicationName()
    {
        return BundleUtil.getString(getVersionBundleName(),
                                    getApplicationNameKey(),
                                    "?");
    }
    
    /**
     * Get the multiline version output. The returned string will have
     * embedded newlines, but no trailing newline.
     *
     * @return the multiline version output.
     */
    public String getVersionDisplay()
    {
        BuildInfo buildInfo = new BuildInfo(getBuildInfoBundleName());
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);

        String versionBundle = getVersionBundleName();
        pw.print(BundleUtil.getString(versionBundle,
                                      getApplicationNameKey(),
                                      "Unknown application"));
        pw.print(", version ");
        pw.println(getVersion());
        pw.println(getCopyright());
        pw.println();
        pw.println("Build:          " + buildInfo.getBuildID());
        pw.println("Build date:     " + buildInfo.getBuildDate());
        pw.println("Built by:       " + buildInfo.getBuildUserID());
        pw.println("Built on:       " +
                   buildInfo.getBuildOperatingSystem());
        pw.println("Build Java VM:  " +
                   buildInfo.getBuildJavaVM());
        pw.println("Build compiler: " +
                   buildInfo.getBuildJavaCompiler());
        pw.print("Ant version:    " +
                 buildInfo.getBuildAntVersion());

       return sw.getBuffer().toString();
    }

    /*----------------------------------------------------------------------*\
                             Protected Abstract Methods
    \*----------------------------------------------------------------------*/

    /**
     * Get the class name of the version resource bundle, which contains
     * values for the product version, copyright, etc.
     *
     * @return the name of the version resource bundle
     */
    protected abstract String getVersionBundleName();

    /**
     * Get the class name of the build info resource bundle, which contains
     * data about when the product was built, generated (presumably)
     * during the build by
     * {@link BuildInfo#makeBuildInfoBundle BuildInfo.makeBuildInfoBundle()}.
     *
     * @return the name of the build info resource bundle
     */
    protected abstract String getBuildInfoBundleName();

    /**
     * Get the key for the version string. This key is presumed to be
     * in the version resource bundle.
     *
     * @return the version string key
     */
    protected abstract String getVersionKey();

    /**
     * Get the key for the copyright string. This key is presumed to be
     * in the version resource bundle.
     *
     * @return the copyright string key
     */
    protected abstract String getCopyrightKey();

    /**
     * Get the key for the name of the utility or application.
     *
     * @return the key
     */
    protected abstract String getApplicationNameKey();

    /*----------------------------------------------------------------------*\
                                Private Methods
    \*----------------------------------------------------------------------*/
}
