/*
 * Copyright (c) 2009, Takeyuki Nagao
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the
 * following conditions are met:
 * 
 *  * Redistributions of source code must retain the above
 *    copyright notice, this list of conditions and the
 *    following disclaimer.
 *  * Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the
 *    following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *    
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 */

package dvi.util;

import java.text.MessageFormat;

public class Benchmark {
  private boolean active = false;
  private long start = 0;
  private long end = 0;
  private long lapsed = 0;
  private long samples = 0;
  private String name;

  public void begin(String name)
  {
    reset();
    start = getCurrentTime();
    this.name = name;
    active = true;
  }
  
  public void reset()
  {
    start = 0;
    end = 0;
    lapsed = 0;
    samples = 0;
    name = null;
    active = false;
  }

  public void addSample()
  {
    addSamples(1);
  }
  
  public void addSamples(int count)
  {
    samples += count;
  }
  
  public void end()
  {
    if (active) {
      end = getCurrentTime();
      lapsed = end - start;
      active = false;
    }
  }
  
  public long getCurrentTime()
  {
    return System.currentTimeMillis();
  }
  
  public long getLapsedTime()
  {
    if (active) {
      long now = getCurrentTime();
      return now - start;
    } else {
      return lapsed;
    }
  }
  
  public long getSamples()
  {
    return samples;
  }

  public double samplesPerSecond(long samples, long lapsed)
  {
    return (double) samples * 1000 / lapsed;
  }

  public String format(String fmt)
  {
    long samples = getSamples();
    long lapsed = getLapsedTime();
    return MessageFormat.format(
             fmt, 
             samples,
             (double) lapsed / 1000,
             samplesPerSecond(samples, lapsed),
             1./samplesPerSecond(samples, lapsed) * 1000
           );
  }

  public String format()
  {
    return format("Benchmark result: " + name + ": "
      + "{0,number} samples in {1,number} sec."
      + " {2,number} samples/sec. "
      + " {3,number,##.###} msec./sample.");
  }

  public String toString()
  {
    return format();
  }

  public long getStartTime() {
    return start;
  }

  public long getEndTime() {
    return end;
  }
}
