/*
 * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 *
 */

package bench;

import java.io.OutputStream;
import java.io.PrintStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.Properties;

/**
 * Benchmark text report generator.
 */
public class TextReporter implements Reporter {

    static final int PRECISION = 3;
    static final int INDEX_WIDTH = 3;
    static final int NAME_WIDTH = 30;
    static final int TIME_WIDTH = 10;
    static final int SCORE_WIDTH = 10;
    static final int PROPNAME_WIDTH = 25;
    static final String[] PROPNAMES = { "os.name", "os.arch", "os.version",
        "java.home", "java.vm.version", "java.vm.vendor", "java.vm.name",
        "java.compiler", "java.class.path", "sun.boot.class.path" };

    OutputStream out;
    String title;

    /**
     * Create TextReporter which writes to the given stream.
     */
    public TextReporter(OutputStream out, String title) {
        this.out = out;
        this.title = title;
    }

    /**
     * Generate text report.
     */
    public void writeReport(BenchInfo[] binfo, Properties props)
        throws IOException
    {
        PrintStream p = new PrintStream(out);
        float total = 0.0f;

        p.println("\n" + title);
        p.println(pad('-', title.length()));
        p.println("");
        for (int i = 0; i < PROPNAMES.length; i++) {
            p.println(fit(PROPNAMES[i] + ":", PROPNAME_WIDTH) +
                    props.getProperty(PROPNAMES[i]));
        }
        p.println("");

        p.println(fit("#", INDEX_WIDTH) + "  " +
                fit("Benchmark Name", NAME_WIDTH) + "  " +
                fit("Time (ms)", TIME_WIDTH) + "  " +
                fit("Score", SCORE_WIDTH));
        p.println(pad('-', INDEX_WIDTH + NAME_WIDTH + TIME_WIDTH +
                    SCORE_WIDTH + 6));

        for (int i = 0; i < binfo.length; i++) {
            BenchInfo b = binfo[i];
            p.print(fit(Integer.toString(i), INDEX_WIDTH) + "  ");
            p.print(fit(b.getName(), NAME_WIDTH) + "  ");
            if (b.getTime() != -1) {
                float score = b.getTime() * b.getWeight();
                total += score;
                p.print(fit(Long.toString(b.getTime()), TIME_WIDTH) + "  ");
                p.println(fit(Util.floatToString(score, PRECISION),
                            SCORE_WIDTH));
            }
            else {
                p.print(fit("--", TIME_WIDTH) + "  ");
                p.println(fit("--", SCORE_WIDTH));
            }
        }
        p.println(pad('-', INDEX_WIDTH + NAME_WIDTH + TIME_WIDTH +
                    SCORE_WIDTH + 6));
        p.println(fit("Total score", INDEX_WIDTH + NAME_WIDTH + TIME_WIDTH +
                    4) + "  " + Util.floatToString(total, PRECISION));
        p.println("");
        p.println("-----");
        p.println("Report generated on " + new Date() + "\n");
        p.println("");
    }

    /**
     * Extend or truncate string so it fits in the given space.
     */
    private static String fit(String s, int len) {
        int slen = s.length();
        StringBuffer buf = new StringBuffer(s);
        buf.setLength(len);
        for (int i = slen; i < len; i++)
            buf.setCharAt(i, ' ');
        return buf.toString();
    }

    /**
     * Return string with given number of chars.
     */
    private static String pad(char c, int len) {
        char[] buf = new char[len];
        Arrays.fill(buf, c);
        return new String(buf);
    }
}
