/*
 * 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.sequencelog.io;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.regex.Pattern;

import org.apache.geode.internal.sequencelog.Transition;

/**
 * Appends events logged using the SequenceLogger to a binary stream.
 *
 */
public class OutputStreamAppender {
  private IdentityHashMap<Object, Integer> writtenObjects = new IdentityHashMap<Object, Integer>();
  private HashMap<String, Integer> writtenStrings = new HashMap<String, Integer>();
  private DataOutputStream outputStream;

  private int nextInt = 0;

  public static final byte EDGE_RECORD = 0x01;
  public static final byte STRING_RECORD = 0x02;

  public OutputStreamAppender(File file) throws FileNotFoundException {
    this(new FileOutputStream(file));
  }

  public OutputStreamAppender(OutputStream out) throws FileNotFoundException {
    this.outputStream = new DataOutputStream(new BufferedOutputStream(out, 256));
    writtenObjects.put(null, Integer.valueOf(-1));
  }

  public void write(Transition edge) throws IOException {
    byte graphType = edge.getType().getId();
    // TODO - really we should deal with null and read it back in as null as well.
    String stateName = edge.getState() == null ? "null" : edge.getState().toString();
    long timestamp = edge.getTimestamp();
    int edgeId = canonalize(edge.getEdgeName());
    int source = canonalize(edge.getSource());
    int dest = canonalize(edge.getDest());

    outputStream.write(EDGE_RECORD);
    outputStream.writeLong(timestamp);
    outputStream.write(graphType);
    writeGraphName(edge.getGraphName());
    outputStream.writeUTF(stateName);
    outputStream.writeInt(edgeId);
    outputStream.writeInt(source);
    outputStream.writeInt(dest);
    outputStream.flush();
  }

  private void writeGraphName(Object graphName) throws IOException {
    boolean isPattern = graphName instanceof Pattern;
    outputStream.writeBoolean(isPattern);
    if (isPattern) {
      final Pattern pattern = (Pattern) graphName;
      outputStream.writeUTF(pattern.pattern());
      outputStream.writeInt(pattern.flags());
    } else {
      outputStream.writeUTF(graphName.toString());
    }
  }

  private int canonalize(Object object) throws IOException {
    Integer id = writtenObjects.get(object);
    if (id != null) {
      return id.intValue();
    }
    String toString = object.toString();
    id = writtenStrings.get(toString);
    if (id != null) {
      return id.intValue();
    }

    id = Integer.valueOf(nextInt++);

    outputStream.write(STRING_RECORD);
    outputStream.writeUTF(toString);

    writtenObjects.put(object, id);
    writtenStrings.put(toString, id);
    return id.intValue();
  }

  public void close() {
    try {
      outputStream.close();
    } catch (IOException e) {
      // do nothing
    }
  }
}
