/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package org.apache.geode.internal.statistics;

import java.io.BufferedOutputStream;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.zip.GZIPOutputStream;

import org.apache.logging.log4j.Logger;

import org.apache.geode.GemFireIOException;
import org.apache.geode.InternalGemFireException;
import org.apache.geode.StatisticDescriptor;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.internal.NanoTimer;
import org.apache.geode.internal.logging.log4j.LogMarker;
import org.apache.geode.internal.net.SocketCreator;
import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * StatArchiveWriter provides APIs to write statistic snapshots to an archive file.
 *
 */
public class StatArchiveWriter implements StatArchiveFormat, SampleHandler {

  private static final Logger logger = LogService.getLogger();

  @MakeNotStatic
  private static volatile String traceStatisticsName = null;
  @MakeNotStatic
  private static volatile String traceStatisticsTypeName = null;
  @MakeNotStatic
  private static volatile int traceResourceInstId = -1;

  private final boolean trace =
      Boolean.getBoolean(DistributionConfig.GEMFIRE_PREFIX + "stats.debug.traceStatArchiveWriter");

  private final Set<ResourceInstance> sampleWrittenForResources = new HashSet<ResourceInstance>();
  private final Set<ResourceInstance> addedResources = new HashSet<ResourceInstance>();
  private final StatArchiveDescriptor archiveDescriptor;
  private long initialDate;
  private final OutputStream outStream;
  private final MyDataOutputStream dataOut;
  private final OutputStream traceOutStream;
  private final PrintStream traceDataOut;
  private long previousMillisTimeStamp;
  private int sampleCount;

  /**
   * Opens a StatArchiveWriter that will archive to the specified file.
   *
   * @throws GemFireIOException if <code>archiveName</code> can not be written to
   */
  public StatArchiveWriter(StatArchiveDescriptor archiveDescriptor) {
    this.archiveDescriptor = archiveDescriptor;

    if (archiveDescriptor.getArchiveName().endsWith(".gz")) {
      try {
        this.outStream =
            new GZIPOutputStream(new FileOutputStream(archiveDescriptor.getArchiveName()), 32768);
      } catch (IOException ex) {
        throw new GemFireIOException(String.format("Could not open %s",
            archiveDescriptor.getArchiveName()), ex);
      }
    } else {
      try {
        this.outStream = new BufferedOutputStream(
            new FileOutputStream(archiveDescriptor.getArchiveName()), 32768);
      } catch (IOException ex) {
        throw new GemFireIOException(String.format("Could not open %s",
            archiveDescriptor.getArchiveName()), ex);
      }
    }

    this.dataOut = new MyDataOutputStream(this.outStream);

    if (this.trace) {
      String traceFileName = archiveDescriptor.getArchiveName() + ".trace";
      try {
        this.traceOutStream = new BufferedOutputStream(new FileOutputStream(traceFileName), 32768);
      } catch (IOException ex) {
        throw new GemFireIOException("Could not open " + traceFileName, ex);
      }
      this.traceDataOut = new PrintStream(this.traceOutStream);
    } else {
      this.traceOutStream = null;
      this.traceDataOut = null;
    }
  }

  public String getArchiveName() {
    return this.archiveDescriptor.getArchiveName();
  }

  public void initialize(long nanosTimeStamp) {
    this.previousMillisTimeStamp = initPreviousMillisTimeStamp(nanosTimeStamp);
    this.initialDate = initInitialDate();
    writeHeader(this.initialDate, this.archiveDescriptor);
  }

  @Override
  public String toString() {
    final StringBuilder sb = new StringBuilder(getClass().getName());
    sb.append("@").append(System.identityHashCode(this)).append("{");
    sb.append("archiveName=").append(this.archiveDescriptor.getArchiveName());
    sb.append("productDescription=").append(this.archiveDescriptor.getProductDescription());
    sb.append("systemDirectoryPath=").append(this.archiveDescriptor.getSystemDirectoryPath());
    sb.append("systemId=").append(this.archiveDescriptor.getSystemId());
    sb.append("systemStartTime=").append(this.archiveDescriptor.getSystemStartTime());
    sb.append("previousMillisTimeStamp=").append(this.previousMillisTimeStamp);
    sb.append("initialDate=").append(this.initialDate);
    return sb.toString();
  }

  /**
   * Closes the statArchiver by flushing its data to disk a closing its output stream.
   *
   * @throws GemFireIOException if the archive file could not be closed.
   */
  public void close() {
    try {
      this.dataOut.flush();
      if (this.trace) {
        this.traceDataOut.flush();
      }
    } catch (IOException ignore) {
    }
    try {
      outStream.close();
      if (this.trace) {
        this.traceOutStream.close();
      }
    } catch (IOException ex) {
      throw new GemFireIOException(
          "Could not close statArchiver file",
          ex);
    }
    if (getSampleCount() == 0) {
      // If we are closing an empty file go ahead and delete it.
      // This prevents the fix for 46917 from leaving a bunch of
      // empty gfs files around.
      deleteFileIfPossible(new File(getArchiveName()));
    }
  }

  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RV_RETURN_VALUE_IGNORED_BAD_PRACTICE",
      justification = "Best effort attempt to delete a GFS file without any samples.")
  private static void deleteFileIfPossible(File file) {
    file.delete();
  }

  /**
   * Returns the number of bytes written so far to this archive. This does not take compression into
   * account.
   */
  public long bytesWritten() {
    return this.dataOut.getBytesWritten();
  }

  protected long initPreviousMillisTimeStamp(long nanosTimeStamp) {
    return NanoTimer.nanosToMillis(nanosTimeStamp);
  }

  protected long initInitialDate() {
    return System.currentTimeMillis();
  }

  protected TimeZone getTimeZone() {
    return Calendar.getInstance().getTimeZone();
  }

  protected String getOSInfo() {
    return System.getProperty("os.name") + " " + System.getProperty("os.version");
  }

  protected String getMachineInfo() {
    String machineInfo = System.getProperty("os.arch");
    try {
      String hostName = SocketCreator.getHostName(SocketCreator.getLocalHost());
      machineInfo += " " + hostName;
    } catch (UnknownHostException ignore) {
    }
    return machineInfo;
  }

  private void writeHeader(long initialDate, StatArchiveDescriptor archiveDescriptor) {
    if (logger.isTraceEnabled(LogMarker.STATISTICS_VERBOSE)) {
      logger.trace(LogMarker.STATISTICS_VERBOSE,
          "StatArchiveWriter#writeHeader initialDate={} archiveDescriptor={}", initialDate,
          archiveDescriptor);
    }
    try {
      this.dataOut.writeByte(HEADER_TOKEN);
      this.dataOut.writeByte(ARCHIVE_VERSION);
      this.dataOut.writeLong(initialDate);
      this.dataOut.writeLong(archiveDescriptor.getSystemId());
      this.dataOut.writeLong(archiveDescriptor.getSystemStartTime());
      TimeZone timeZone = getTimeZone();
      this.dataOut.writeInt(timeZone.getRawOffset());
      this.dataOut.writeUTF(timeZone.getID());
      this.dataOut.writeUTF(archiveDescriptor.getSystemDirectoryPath());
      this.dataOut.writeUTF(archiveDescriptor.getProductDescription());
      this.dataOut.writeUTF(getOSInfo());
      this.dataOut.writeUTF(getMachineInfo());

      if (this.trace) {
        this.traceDataOut.println("writeHeader traceStatisticsName: " + traceStatisticsName);
        this.traceDataOut
            .println("writeHeader traceStatisticsTypeName: " + traceStatisticsTypeName);
        this.traceDataOut.println("writeHeader#writeByte HEADER_TOKEN: " + HEADER_TOKEN);
        this.traceDataOut.println("writeHeader#writeByte ARCHIVE_VERSION: " + ARCHIVE_VERSION);
        this.traceDataOut.println("writeHeader#writeLong initialDate: " + initialDate);
        this.traceDataOut.println("writeHeader#writeLong archiveDescriptor.getSystemId(): "
            + archiveDescriptor.getSystemId());
        this.traceDataOut.println("writeHeader#writeLong archiveDescriptor.getSystemStartTime(): "
            + archiveDescriptor.getSystemStartTime());
        this.traceDataOut
            .println("writeHeader#writeInt timeZone.getRawOffset(): " + timeZone.getRawOffset());
        this.traceDataOut.println("writeHeader#writeUTF timeZone.getID(): " + timeZone.getID());
        this.traceDataOut
            .println("writeHeader#writeUTF archiveDescriptor.getSystemDirectoryPath(): "
                + archiveDescriptor.getSystemDirectoryPath());
        this.traceDataOut.println("writeHeader#writeUTF archiveDescriptor.getProductDescription(): "
            + archiveDescriptor.getProductDescription());
        this.traceDataOut.println("writeHeader#writeUTF getOSInfo(): " + getOSInfo());
        this.traceDataOut.println("writeHeader#writeUTF getMachineInfo(): " + getMachineInfo());
      }
    } catch (IOException ex) {
      throw new GemFireIOException(
          "Failed writing header to statistic archive",
          ex);
    }
  }

  @Override
  public void allocatedResourceType(ResourceType resourceType) {
    if (logger.isTraceEnabled(LogMarker.STATISTICS_VERBOSE)) {
      logger.trace(LogMarker.STATISTICS_VERBOSE,
          "StatArchiveWriter#allocatedResourceType resourceType={}", resourceType);
    }
    if (resourceType.getStatisticDescriptors().length >= ILLEGAL_STAT_OFFSET) {
      throw new InternalGemFireException(
          String.format("Could not archive type %s because it had more than %s statistics.",
              new Object[] {resourceType.getStatisticsType().getName(),
                  Integer.valueOf(ILLEGAL_STAT_OFFSET - 1)}));
    }
    // write the type to the archive
    try {
      this.dataOut.writeByte(RESOURCE_TYPE_TOKEN);
      this.dataOut.writeInt(resourceType.getId());
      this.dataOut.writeUTF(resourceType.getStatisticsType().getName());
      this.dataOut.writeUTF(resourceType.getStatisticsType().getDescription());
      StatisticDescriptor[] stats = resourceType.getStatisticDescriptors();
      this.dataOut.writeShort(stats.length);
      if (this.trace && (traceStatisticsTypeName == null
          || traceStatisticsTypeName.equals(resourceType.getStatisticsType().getName()))) {
        this.traceDataOut
            .println("allocatedResourceType#writeByte RESOURCE_TYPE_TOKEN: " + RESOURCE_TYPE_TOKEN);
        this.traceDataOut.println(
            "allocatedResourceType#writeInt resourceType.getId(): " + resourceType.getId());
        this.traceDataOut
            .println("allocatedResourceType#writeUTF resourceType.getStatisticsType().getName(): "
                + resourceType.getStatisticsType().getName());
        this.traceDataOut.println(
            "allocatedResourceType#writeUTF resourceType.getStatisticsType().getDescription(): "
                + resourceType.getStatisticsType().getDescription());
        this.traceDataOut.println("allocatedResourceType#writeShort stats.length: " + stats.length);
      }
      for (int i = 0; i < stats.length; i++) {
        this.dataOut.writeUTF(stats[i].getName());
        this.dataOut.writeByte(((StatisticDescriptorImpl) stats[i]).getTypeCode());
        this.dataOut.writeBoolean(stats[i].isCounter());
        this.dataOut.writeBoolean(stats[i].isLargerBetter());
        this.dataOut.writeUTF(stats[i].getUnit());
        this.dataOut.writeUTF(stats[i].getDescription());
        if (this.trace && (traceStatisticsTypeName == null
            || traceStatisticsTypeName.equals(resourceType.getStatisticsType().getName()))) {
          this.traceDataOut
              .println("allocatedResourceType#writeUTF stats[i].getName(): " + stats[i].getName());
          this.traceDataOut.println(
              "allocatedResourceType#writeByte ((StatisticDescriptorImpl)stats[i]).getTypeCode(): "
                  + ((StatisticDescriptorImpl) stats[i]).getTypeCode());
          this.traceDataOut.println(
              "allocatedResourceType#writeBoolean stats[i].isCounter(): " + stats[i].isCounter());
          this.traceDataOut.println("allocatedResourceType#writeBoolean stats[i].isLargerBetter(): "
              + stats[i].isLargerBetter());
          this.traceDataOut
              .println("allocatedResourceType#writeUTF stats[i].getUnit(): " + stats[i].getUnit());
          this.traceDataOut.println("allocatedResourceType#writeUTF stats[i].getDescription(): "
              + stats[i].getDescription());
        }
      }
    } catch (IOException ex) {
      throw new GemFireIOException(
          "Failed writing new resource type to statistic archive",
          ex);
    }
  }

  @Override
  @edu.umd.cs.findbugs.annotations.SuppressWarnings(
      value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD",
      justification = "This is only for debugging and there is never more than one instance being traced because there is only one stat sampler.")
  public void allocatedResourceInstance(ResourceInstance statResource) {
    if (logger.isTraceEnabled(LogMarker.STATISTICS_VERBOSE)) {
      logger.trace(LogMarker.STATISTICS_VERBOSE,
          "StatArchiveWriter#allocatedResourceInstance statResource={}", statResource);
    }
    if (statResource.getResourceType().getStatisticDescriptors().length >= ILLEGAL_STAT_OFFSET) {
      throw new InternalGemFireException(
          String.format("Could not archive type %s because it had more than %s statistics.",

              new Object[] {statResource.getResourceType().getStatisticsType().getName(),
                  Integer.valueOf(ILLEGAL_STAT_OFFSET - 1)}));
    }
    if (statResource.getStatistics().isClosed()) {
      return;
    }
    this.addedResources.add(statResource);
    try {
      this.dataOut.writeByte(RESOURCE_INSTANCE_CREATE_TOKEN);
      this.dataOut.writeInt(statResource.getId());
      this.dataOut.writeUTF(statResource.getStatistics().getTextId());
      this.dataOut.writeLong(statResource.getStatistics().getNumericId());
      this.dataOut.writeInt(statResource.getResourceType().getId());
      if (this.trace
          && (traceStatisticsName == null
              || traceStatisticsName.equals(statResource.getStatistics().getTextId()))
          && (traceStatisticsTypeName == null || traceStatisticsTypeName
              .equals(statResource.getResourceType().getStatisticsType().getName()))) {
        traceResourceInstId = statResource.getId();
        this.traceDataOut.println("writeHeader traceResourceInstId: " + traceResourceInstId);
        this.traceDataOut
            .println("allocatedResourceInstance#writeByte RESOURCE_INSTANCE_CREATE_TOKEN: "
                + RESOURCE_INSTANCE_CREATE_TOKEN);
        this.traceDataOut.println(
            "allocatedResourceInstance#writeInt statResource.getId(): " + statResource.getId());
        this.traceDataOut
            .println("allocatedResourceInstance#writeUTF statResource.getStatistics().getTextId(): "
                + statResource.getStatistics().getTextId());
        this.traceDataOut.println(
            "allocatedResourceInstance#writeLong statResource.getStatistics().getNumericId(): "
                + statResource.getStatistics().getNumericId());
        this.traceDataOut
            .println("allocatedResourceInstance#writeInt statResource.getResourceType().getId(): "
                + statResource.getResourceType().getId());
      }
    } catch (IOException ex) {
      throw new GemFireIOException(
          "Failed writing new resource instance to statistic archive",
          ex);
    }
  }

  @Override
  public void destroyedResourceInstance(ResourceInstance resourceInstance) {
    if (logger.isTraceEnabled(LogMarker.STATISTICS_VERBOSE)) {
      logger.trace(LogMarker.STATISTICS_VERBOSE,
          "StatArchiveWriter#destroyedResourceInstance resourceInstance={}", resourceInstance);
    }
    if (!this.addedResources.contains(resourceInstance)) { // Fix for bug #45377
      return;
    }

    this.sampleWrittenForResources.remove(resourceInstance);
    this.addedResources.remove(resourceInstance);

    try {
      this.dataOut.writeByte(RESOURCE_INSTANCE_DELETE_TOKEN);
      this.dataOut.writeInt(resourceInstance.getId());
      if (this.trace
          && (traceStatisticsName == null
              || traceStatisticsName.equals(resourceInstance.getStatistics().getTextId()))
          && (traceStatisticsTypeName == null || traceStatisticsTypeName
              .equals(resourceInstance.getResourceType().getStatisticsType().getName()))) {
        this.traceDataOut
            .println("destroyedResourceInstance#writeByte RESOURCE_INSTANCE_DELETE_TOKEN: "
                + RESOURCE_INSTANCE_DELETE_TOKEN);
        this.traceDataOut.println("destroyedResourceInstance#writeInt resourceInstance.getId(): "
            + resourceInstance.getId());
      }
    } catch (IOException ex) {
      throw new GemFireIOException(
          "Failed writing delete resource instance to statistic archive",
          ex);
    }
  }

  static long calcDelta(long previousMillis, long currentMillis) {
    long delta = currentMillis - previousMillis;
    if (delta <= 0) {
      throw new IllegalArgumentException(
          "Sample timestamp must be greater than previous timestamp (millisTimeStamp is "
              + currentMillis + ", previousMillis is " + previousMillis + " and delta is " + delta
              + ").");
    }
    return delta;
  }

  private void writeTimeStamp(long nanosTimeStamp) throws IOException {
    final long millisTimeStamp = NanoTimer.nanosToMillis(nanosTimeStamp);
    final long delta = calcDelta(this.previousMillisTimeStamp, millisTimeStamp);
    if (logger.isTraceEnabled(LogMarker.STATISTICS_VERBOSE)) {
      logger.trace(LogMarker.STATISTICS_VERBOSE,
          "StatArchiveWriter#writeTimeStamp millisTimeStamp={}, delta={}", millisTimeStamp,
          (int) delta);
    }
    if (delta > MAX_SHORT_TIMESTAMP) {
      if (delta > Integer.MAX_VALUE) {
        throw new InternalGemFireException(
            String.format("timeStamp delta %s was greater than %s",

                new Object[] {Long.valueOf(delta), Integer.valueOf(Integer.MAX_VALUE)}));
      }
      this.dataOut.writeShort(INT_TIMESTAMP_TOKEN);
      this.dataOut.writeInt((int) delta);
      if (this.trace) {
        this.traceDataOut
            .println("writeTimeStamp#writeShort INT_TIMESTAMP_TOKEN: " + INT_TIMESTAMP_TOKEN);
        this.traceDataOut.println("writeTimeStamp#writeInt (int)delta: " + (int) delta);
      }
    } else {
      this.dataOut.writeShort((int) delta);
      if (this.trace) {
        this.traceDataOut.println("writeTimeStamp#writeShort (int)delta: " + (int) delta);
      }
    }
    this.previousMillisTimeStamp = millisTimeStamp;
  }

  /**
   * Writes the resource instance id to the <code>dataOut</code> stream.
   */
  private void writeResourceInst(int instId) throws IOException {
    if (logger.isTraceEnabled(LogMarker.STATISTICS_VERBOSE)) {
      logger.trace(LogMarker.STATISTICS_VERBOSE, "StatArchiveWriter#writeResourceInst instId={}",
          instId);
    }
    if (instId > MAX_BYTE_RESOURCE_INST_ID) {
      if (instId > MAX_SHORT_RESOURCE_INST_ID) {
        this.dataOut.writeByte(INT_RESOURCE_INST_ID_TOKEN);
        this.dataOut.writeInt(instId);
        if (this.trace && (traceResourceInstId == -1 || traceResourceInstId == instId)) {
          this.traceDataOut.println("writeResourceInst#writeByte INT_RESOURCE_INST_ID_TOKEN: "
              + INT_RESOURCE_INST_ID_TOKEN);
          this.traceDataOut.println("writeResourceInst#writeInt instId: " + instId);
        }
      } else {
        this.dataOut.writeByte(SHORT_RESOURCE_INST_ID_TOKEN);
        this.dataOut.writeShort(instId);
        if (this.trace && (traceResourceInstId == -1 || traceResourceInstId == instId)) {
          this.traceDataOut.println("writeResourceInst#writeByte SHORT_RESOURCE_INST_ID_TOKEN: "
              + SHORT_RESOURCE_INST_ID_TOKEN);
          this.traceDataOut.println("writeResourceInst#writeShort instId: " + instId);
        }
      }
    } else {
      this.dataOut.writeByte(instId);
      if (this.trace && (traceResourceInstId == -1 || traceResourceInstId == instId)) {
        if (instId == ILLEGAL_RESOURCE_INST_ID) {
          this.traceDataOut.println(
              "writeResourceInst#writeByte ILLEGAL_RESOURCE_INST_ID: " + ILLEGAL_RESOURCE_INST_ID);
        } else {
          this.traceDataOut.println("writeResourceInst#writeByte instId: " + instId);
        }
      }
    }
  }

  @Override
  public void sampled(long nanosTimeStamp, List<ResourceInstance> resourceInstances) {
    if (logger.isTraceEnabled(LogMarker.STATISTICS_VERBOSE)) {
      logger.trace(LogMarker.STATISTICS_VERBOSE,
          "StatArchiveWriter#sampled nanosTimeStamp={}, resourceInstances={}", nanosTimeStamp,
          resourceInstances);
    }
    try {
      this.dataOut.writeByte(SAMPLE_TOKEN);
      if (this.trace) {
        this.traceDataOut.println("sampled#writeByte SAMPLE_TOKEN: " + SAMPLE_TOKEN);
      }
      writeTimeStamp(nanosTimeStamp);
      for (ResourceInstance ri : resourceInstances) {
        writeSample(ri);
      }
      writeResourceInst(ILLEGAL_RESOURCE_INST_ID);
      this.dataOut.flush();
      if (this.trace) {
        this.traceDataOut.flush();
      }
    } catch (IOException ex) {
      throw new GemFireIOException(
          "Failed writing sample to statistic archive",
          ex);
    }
    this.sampleCount++; // only inc after sample done w/o an exception thrown
  }

  public int getSampleCount() {
    return this.sampleCount;
  }

  private void writeSample(ResourceInstance ri) throws IOException {
    final boolean isDebugEnabled_STATISTICS = logger.isTraceEnabled(LogMarker.STATISTICS_VERBOSE);
    if (isDebugEnabled_STATISTICS) {
      logger.trace(LogMarker.STATISTICS_VERBOSE, "StatArchiveWriter#writeSample ri={}", ri);
    }
    if (this.trace
        && (traceStatisticsName == null
            || traceStatisticsName.equals(ri.getStatistics().getTextId()))
        && (traceStatisticsTypeName == null || traceStatisticsTypeName
            .equals(ri.getResourceType().getStatisticsType().getName()))) {
      this.traceDataOut.println("writeSample#writeSample for ri=" + ri);
    }
    if (ri.getStatistics().isClosed()) {
      return;
    }
    StatisticDescriptor[] stats = ri.getResourceType().getStatisticDescriptors();
    if (stats.length > 254) {
      throw new Error("StatisticsType " + ri.getResourceType().getStatisticsType().getName()
          + " has too many stats: " + stats.length);
    }
    boolean wroteInstId = false;
    boolean checkForChange = true;

    if (!this.sampleWrittenForResources.contains(ri)) {
      // first time for this instance so all values need to be written
      checkForChange = false;
      this.sampleWrittenForResources.add(ri);
    }

    long[] previousStatValues = ri.getPreviousStatValues();
    if (isDebugEnabled_STATISTICS) {
      logger.trace(LogMarker.STATISTICS_VERBOSE,
          "StatArchiveWriter#writeSample checkForChange={}, previousStatValues={}, stats.length={}",
          checkForChange, Arrays.toString(previousStatValues), stats.length);
    }
    if (previousStatValues == null) {
      previousStatValues = new long[stats.length];
      ri.setPreviousStatValues(previousStatValues);
    }

    int statsWritten = 0;
    try {
      for (int i = 0; i < stats.length; i++) {
        long value = ri.getLatestStatValues()[i];
        if (!checkForChange || value != previousStatValues[i]) {
          long delta = checkForChange ? value - previousStatValues[i] : value;
          if (!wroteInstId) {
            wroteInstId = true;
            writeResourceInst(ri.getId());
          }
          this.dataOut.writeByte(i);
          if (this.trace
              && (traceStatisticsName == null
                  || traceStatisticsName.equals(ri.getStatistics().getTextId()))
              && (traceStatisticsTypeName == null || traceStatisticsTypeName
                  .equals(ri.getResourceType().getStatisticsType().getName()))) {
            this.traceDataOut.println("writeSample#writeByte i: " + i);
          }
          if (isDebugEnabled_STATISTICS) {
            logger.trace(LogMarker.STATISTICS_VERBOSE,
                "StatArchiveWriter#writeStatValue stats[{}]={}, delta={}", i, stats[i], delta);
          }
          writeStatValue(stats[i], delta, this.dataOut);
          if (this.trace
              && (traceStatisticsName == null
                  || traceStatisticsName.equals(ri.getStatistics().getTextId()))
              && (traceStatisticsTypeName == null || traceStatisticsTypeName
                  .equals(ri.getResourceType().getStatisticsType().getName()))) {
            byte typeCode = ((StatisticDescriptorImpl) stats[i]).getTypeCode();
            switch (typeCode) {
              case BYTE_CODE:
                this.traceDataOut.println(
                    "writeStatValue#writeByte " + typeCodeToString(typeCode) + " delta: " + delta);
                break;
              case SHORT_CODE:
                this.traceDataOut.println(
                    "writeStatValue#writeShort" + typeCodeToString(typeCode) + " delta: " + delta);
                break;
              case INT_CODE:
              case FLOAT_CODE:
              case LONG_CODE:
              case DOUBLE_CODE:
                this.traceDataOut.println("writeStatValue#writeCompactValue "
                    + typeCodeToString(typeCode) + " delta: " + delta);
                break;
              default:
            }
          }
        }
      }
    } catch (IllegalStateException closedEx) {
      // resource was closed causing getStatValue to throw this exception
    }

    if (wroteInstId) {
      this.dataOut.writeByte(ILLEGAL_STAT_OFFSET);
      if (this.trace
          && (traceStatisticsName == null
              || traceStatisticsName.equals(ri.getStatistics().getTextId()))
          && (traceStatisticsTypeName == null || traceStatisticsTypeName
              .equals(ri.getResourceType().getStatisticsType().getName()))) {
        this.traceDataOut
            .println("writeSample#writeByte ILLEGAL_STAT_OFFSET: " + ILLEGAL_STAT_OFFSET);
      }
    }
    if (isDebugEnabled_STATISTICS) {
      logger.trace(LogMarker.STATISTICS_VERBOSE, "StatArchiveWriter#writeSample statsWritten={}",
          statsWritten);
    }
  }

  public static void writeCompactValue(long v, DataOutput dataOut) throws IOException {
    if (v <= MAX_1BYTE_COMPACT_VALUE && v >= MIN_1BYTE_COMPACT_VALUE) {
      dataOut.writeByte((int) v);
    } else if (v <= MAX_2BYTE_COMPACT_VALUE && v >= MIN_2BYTE_COMPACT_VALUE) {
      dataOut.writeByte(COMPACT_VALUE_2_TOKEN);
      dataOut.writeShort((int) v);
    } else {
      byte[] buffer = new byte[8];
      int idx = 0;
      long originalValue = v;
      if (v < 0) {
        while (v != -1 && v != 0) {
          buffer[idx++] = (byte) (v & 0xFF);
          v >>= 8;
        }
        // On windows v goes to zero somtimes; seems like a bug
        if (v == 0) {
          // when this happens we end up with a bunch of -1 bytes
          // so strip off the high order ones
          while (buffer[idx - 1] == -1) {
            idx--;
          }
        }
        if ((buffer[idx - 1] & 0x80) == 0) {
          /*
           * If the most significant byte does not have its high order bit set then add a -1 byte so
           * we know this is a negative number
           */
          buffer[idx++] = -1;
        }
      } else {
        while (v != 0) {
          buffer[idx++] = (byte) (v & 0xFF);
          v >>= 8;
        }
        if ((buffer[idx - 1] & 0x80) != 0) {
          /*
           * If the most significant byte has its high order bit set then add a zero byte so we know
           * this is a positive number
           */
          buffer[idx++] = 0;
        }
      }
      if (idx <= 2) {
        throw new InternalGemFireException(
            String.format("Expected idx to be greater than 2. It was %s for the value %s",

                new Object[] {Integer.valueOf(idx), Long.valueOf(originalValue)}));
      }
      int token = COMPACT_VALUE_2_TOKEN + (idx - 2);
      dataOut.writeByte(token);
      for (int i = idx - 1; i >= 0; i--) {
        dataOut.writeByte(buffer[i]);
      }
    }
  }

  public static long readCompactValue(DataInput dataIn) throws IOException {
    long v = dataIn.readByte();
    boolean dump = false;
    if (dump) {
      System.out.print("compactValue(byte1)=" + v);
    }
    if (v < MIN_1BYTE_COMPACT_VALUE) {
      if (v == COMPACT_VALUE_2_TOKEN) {
        v = dataIn.readShort();
        if (dump) {
          System.out.print("compactValue(short)=" + v);
        }
      } else {
        int bytesToRead = ((byte) v - COMPACT_VALUE_2_TOKEN) + 2;
        v = dataIn.readByte(); // note the first byte will be a signed byte.
        if (dump) {
          System.out.print("compactValue(" + bytesToRead + ")=" + v);
        }
        bytesToRead--;
        while (bytesToRead > 0) {
          v <<= 8;
          v |= dataIn.readUnsignedByte();
          bytesToRead--;
        }
      }
    }
    return v;
  }

  protected static void writeStatValue(StatisticDescriptor f, long v, DataOutput dataOut)
      throws IOException {
    byte typeCode = ((StatisticDescriptorImpl) f).getTypeCode();
    writeStatValue(typeCode, v, dataOut);
  }

  public static void writeStatValue(byte typeCode, long v, DataOutput dataOut) throws IOException {
    switch (typeCode) {
      case BYTE_CODE:
        dataOut.writeByte((int) v);
        break;
      case SHORT_CODE:
        dataOut.writeShort((int) v);
        break;
      case INT_CODE:
      case FLOAT_CODE:
      case LONG_CODE:
      case DOUBLE_CODE:
        writeCompactValue(v, dataOut);
        break;
      default:
        throw new InternalGemFireException(String.format("Unexpected type code %s",
            Byte.valueOf(typeCode)));
    }
  }

  protected static void setTraceFilter(String traceStatisticsName, String traceStatisticsTypeName) {
    StatArchiveWriter.traceStatisticsName = traceStatisticsName;
    StatArchiveWriter.traceStatisticsTypeName = traceStatisticsTypeName;
    StatArchiveWriter.traceResourceInstId = -1;
  }

  protected static void clearTraceFilter() {
    StatArchiveWriter.traceStatisticsName = null;
    StatArchiveWriter.traceStatisticsTypeName = null;
    StatArchiveWriter.traceResourceInstId = -1;
  }

  private static String typeCodeToString(byte typeCode) {
    switch (typeCode) {
      case BYTE_CODE:
        return "BYTE_CODE";
      case SHORT_CODE:
        return "SHORT_CODE";
      case INT_CODE:
        return "INT_CODE";
      case FLOAT_CODE:
        return "FLOAT_CODE";
      case LONG_CODE:
        return "LONG_CODE";
      case DOUBLE_CODE:
        return "DOUBLE_CODE";
      default:
        return "unknown typeCode " + typeCode;
    }
  }

  private static class MyDataOutputStream implements DataOutput {
    private long bytesWritten = 0;
    private final DataOutputStream dataOut;

    public MyDataOutputStream(OutputStream out) {
      this.dataOut = new DataOutputStream(out);
    }

    public long getBytesWritten() {
      return this.bytesWritten;
    }

    public void flush() throws IOException {
      this.dataOut.flush();
    }

    @SuppressWarnings("unused")
    public void close() throws IOException {
      this.dataOut.close();
    }

    @Override
    public void write(int b) throws IOException {
      throw new RuntimeException(
          "method unimplemented");
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
      throw new RuntimeException(
          "method unimplemented");
    }

    @Override
    public void write(byte[] b) throws IOException {
      throw new RuntimeException(
          "method unimplemented");
    }

    @Override
    public void writeBytes(String v) throws IOException {
      throw new RuntimeException(
          "method unimplemented");
    }

    @Override
    public void writeChar(int v) throws IOException {
      throw new RuntimeException(
          "method unimplemented");
    }

    @Override
    public void writeChars(String v) throws IOException {
      throw new RuntimeException(
          "method unimplemented");
    }

    @Override
    public void writeDouble(double v) throws IOException {
      throw new RuntimeException(
          "method unimplemented");
    }

    @Override
    public void writeFloat(float v) throws IOException {
      throw new RuntimeException(
          "method unimplemented");
    }

    @Override
    public void writeBoolean(boolean v) throws IOException {
      this.dataOut.writeBoolean(v);
      this.bytesWritten += 1;
    }

    @Override
    public void writeByte(int v) throws IOException {
      this.dataOut.writeByte(v);
      this.bytesWritten += 1;
    }

    @Override
    public void writeShort(int v) throws IOException {
      this.dataOut.writeShort(v);
      this.bytesWritten += 2;
    }

    @Override
    public void writeInt(int v) throws IOException {
      this.dataOut.writeInt(v);
      this.bytesWritten += 4;
    }

    @Override
    public void writeLong(long v) throws IOException {
      this.dataOut.writeLong(v);
      this.bytesWritten += 8;
    }

    @Override
    public void writeUTF(String v) throws IOException {
      this.dataOut.writeUTF(v);
      this.bytesWritten += v.length() + 2; // this is the minimum. The max is v.size()*3 +2
    }
  }
}
