/*
 * Copyright (c) 2008, 2009, 2011, 2012, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.net4j.util.io;

import org.eclipse.net4j.util.CheckUtil;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Eike Stepper
 * @since 2.0
 */
public class StringCompressor implements StringIO
{
  /**
   * @since 3.0
   */
  public static boolean BYPASS = false;

  private static final int NULL_ID = 0;

  private static final int INFO_FOLLOWS = Integer.MIN_VALUE;

  private static final byte NOTHING_FOLLOWS = 1;

  private static final byte STRING_FOLLOWS = 2;

  private static final byte ACK_FOLLOWS = 3;

  private static final boolean DEBUG = false;

  private static final byte DEBUG_STRING = -1;

  private static final byte DEBUG_INT = -2;

  private static final byte DEBUG_BYTE = -3;

  private boolean client;

  private int lastID;

  private Map<String, ID> stringToID = new HashMap<String, ID>();

  private Map<Integer, String> idToString = new HashMap<Integer, String>();

  private List<Integer> pendingAcknowledgements = new ArrayList<Integer>();

  /**
   * Creates a StringCompressor instance.
   *
   * @param client
   *          Must be different on both sides of the stream.
   */
  public StringCompressor(boolean client)
  {
    this.client = client;
  }

  public boolean isClient()
  {
    return client;
  }

  public void write(ExtendedDataOutput out, String string) throws IOException
  {
    if (DEBUG)
    {
      trace("BEGIN", string);
    }

    if (string == null)
    {
      writeInt(out, NULL_ID);
      return;
    }

    ID id;
    List<Integer> acknowledgements = null;
    boolean stringFollows = false;
    synchronized (this)
    {
      id = stringToID.get(string);
      if (id == null)
      {
        lastID += client ? 1 : -1;
        id = new ID(lastID);

        stringToID.put(string, id);
        idToString.put(id.getValue(), string);
        stringFollows = true;
      }
      else if (!id.isAcknowledged())
      {
        stringFollows = true;
      }

      if (!pendingAcknowledgements.isEmpty())
      {
        acknowledgements = pendingAcknowledgements;
        pendingAcknowledgements = new ArrayList<Integer>();
      }
    }

    if (stringFollows || acknowledgements != null)
    {
      writeInt(out, INFO_FOLLOWS);
      writeInt(out, id.getValue());

      if (stringFollows)
      {
        writeByte(out, STRING_FOLLOWS);
        writeString(out, string);
      }

      if (acknowledgements != null)
      {
        for (int ack : acknowledgements)
        {
          writeByte(out, ACK_FOLLOWS);
          writeInt(out, ack);
        }
      }

      writeByte(out, NOTHING_FOLLOWS);
    }
    else
    {
      writeInt(out, id.getValue());
    }
  }

  public String read(ExtendedDataInput in) throws IOException
  {
    if (DEBUG)
    {
      trace("BEGIN", "?");
    }

    int id = readInt(in);
    if (id == NULL_ID)
    {
      return null;
    }

    String string = null;
    List<Integer> acks = null;
    if (id == INFO_FOLLOWS)
    {
      id = readInt(in);

      boolean moreInfos = true;
      while (moreInfos)
      {
        byte info = readByte(in);
        switch (info)
        {
        case NOTHING_FOLLOWS:
          moreInfos = false;
          break;

        case STRING_FOLLOWS:
          string = readString(in);
          break;

        case ACK_FOLLOWS:
          if (acks == null)
          {
            acks = new ArrayList<Integer>();
          }

          acks.add(readInt(in));
          break;

        default:
          throw new IOException("Invalid info: " + info); //$NON-NLS-1$
        }
      }
    }

    synchronized (this)
    {
      acknowledge(acks);
      if (string != null)
      {
        stringToID.put(string, new ID(id));
        idToString.put(id, string);
        pendingAcknowledgements.add(id);
      }
      else
      {
        string = idToString.get(id);
        if (string == null)
        {
          throw new IOException("String ID unknown: " + id); //$NON-NLS-1$
        }
      }
    }

    return string;
  }

  @Override
  public String toString()
  {
    return MessageFormat.format("StringCompressor[client={0}]", client); //$NON-NLS-1$
  }

  private void acknowledge(List<Integer> acks)
  {
    if (acks != null)
    {
      for (int value : acks)
      {
        String string = idToString.get(value);
        if (string != null)
        {
          ID id = stringToID.get(string);
          if (id != null)
          {
            id.setAcknowledged();
          }
        }
      }
    }
  }

  private void writeByte(ExtendedDataOutput out, byte value) throws IOException
  {
    if (DEBUG)
    {
      trace("writeByte", value);
      out.writeByte(DEBUG_BYTE);
    }

    out.writeByte(value);
  }

  private void writeInt(ExtendedDataOutput out, int value) throws IOException
  {
    if (DEBUG)
    {
      trace("writeInt", value);
      out.writeByte(DEBUG_INT);
    }

    out.writeInt(value);
  }

  /**
   * @since 3.0
   */
  protected void writeString(ExtendedDataOutput out, String value) throws IOException
  {
    if (DEBUG)
    {
      trace("writeString", value);
      out.writeByte(DEBUG_STRING);
    }

    out.writeString(value);
  }

  private byte readByte(ExtendedDataInput in) throws IOException
  {
    if (DEBUG)
    {
      byte type = in.readByte();
      if (DEBUG_BYTE != type)
      {
        throw new IOException("Not a byte value (type=" + type + ")"); //$NON-NLS-1$
      }
    }

    byte value = in.readByte();
    if (DEBUG)
    {
      trace("readByte", value);
    }

    return value;
  }

  private int readInt(ExtendedDataInput in) throws IOException
  {
    if (DEBUG)
    {
      byte type = in.readByte();
      if (DEBUG_INT != type)
      {
        throw new IOException("Not an integer value (type=" + type + ")"); //$NON-NLS-1$
      }
    }

    int value = in.readInt();
    if (DEBUG)
    {
      trace("readInt", value);
    }

    return value;
  }

  /**
   * @since 3.0
   */
  protected String readString(ExtendedDataInput in) throws IOException
  {
    if (DEBUG)
    {
      byte type = in.readByte();
      if (DEBUG_STRING != type)
      {
        throw new IOException("Not a string value (type=" + type + ")"); //$NON-NLS-1$
      }
    }

    String value = in.readString();
    if (DEBUG)
    {
      trace("readString", value);
    }

    return value;
  }

  private void trace(String prefix, Object value)
  {
    if (value instanceof Byte)
    {
      byte opcode = (Byte)value;
      switch (opcode)
      {
      case NOTHING_FOLLOWS:
        value = "NOTHING_FOLLOWS";
        break;

      case STRING_FOLLOWS:
        value = "STRING_FOLLOWS";
        break;

      case ACK_FOLLOWS:
        value = "STRING_FOLLOWS";
        break;
      }
    }

    if (value instanceof Integer)
    {
      int opcode = (Integer)value;
      if (opcode == INFO_FOLLOWS)
      {
        value = "INFO_FOLLOWS";
      }
    }

    String msg = "[" + Thread.currentThread().getName() + "] " + prefix + ": " + value;
    if (!client)
    {
      msg = "                                                                   " + msg;
    }

    IOUtil.OUT().println(msg);
  }

  /**
   * @author Eike Stepper
   */
  private static final class ID
  {
    private int value;

    private boolean acknowledged;

    public ID(int value)
    {
      CheckUtil.checkArg(value != INFO_FOLLOWS, "value");
      this.value = value;
    }

    public int getValue()
    {
      return value;
    }

    public boolean isAcknowledged()
    {
      return acknowledged;
    }

    public void setAcknowledged()
    {
      acknowledged = true;
    }
  }

  /**
   * @author Eike Stepper
   * @since 3.0
   */
  public static class Counting extends StringCompressor
  {
    private long stringsRead;

    private long stringsWritten;

    public Counting(boolean client)
    {
      super(client);
    }

    public long getStringsRead()
    {
      return stringsRead;
    }

    public long getStringsWritten()
    {
      return stringsWritten;
    }

    @Override
    protected String readString(ExtendedDataInput in) throws IOException
    {
      synchronized (this)
      {
        ++stringsRead;
      }

      return super.readString(in);
    }

    @Override
    protected void writeString(ExtendedDataOutput out, String value) throws IOException
    {
      synchronized (this)
      {
        ++stringsWritten;
      }

      super.writeString(out, value);
    }
  }
}
