/*
 * 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.uima.cas.impl;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;

import org.apache.uima.UIMARuntimeException;

/**
 * Common de/serialization 
 */
public class CommonSerDes {
  
  int version1;
  int version2;
  
  boolean isDelta;
  boolean isCompressed;
  
  /*********************************************
   * HEADERS
   * Serialization versioning
   *   There are 1 or 2 words used for versioning.
   *     Compressed formats and plain formats with bit xx on in first word use 2nd word
   *     
   *   First word:
   *   
   *     - bit in 0x01 position: on for binary non-delta (redundant)   
   *     - bit in 0x02 position: on means delta, off - not delta
   *     - bit in 0x04 position: on means compressed, off means plain binary
   *     - bit in 0x08 position: on means typer system included
   *     - bits  0xF8 reserved
   *     
   *     - byte in 0xFF 00 position: incrementing (starting w/ 0) version
   *     
   *         Form 4:  0 = original (UIMA v2)
   *                  1 = fixes to original found during V3 development
   *                  2 = V3
   *                       
   *     - byte in 0xFF 00 00  position: special flags with some shared meaning
   *       -- bit 0x01 00 00: V3 formats
   *         
   *   Second word:
   *     - bit in 0x01 position: on means form6, off = form 4 
   *********************************************/
  
  public static class Header {
    boolean isDelta;
    boolean isCompressed;
    boolean isV3style;
    boolean form4;
    boolean form6;
    boolean typeSystemIncluded;
    byte seqVersionNbr;
    boolean isV3;
    boolean swap;
    int v;      // for error messages

    
    Reading reading;
    
    public Header delta() {isDelta = true;  return this; }
    public Header delta(boolean v2) {isDelta = v2;  return this; }
    public Header form4() {isCompressed = form4 = true; form6 = false; return this; }
    public Header form6() {isCompressed = form6 = true; form4 = false; return this; }
    public Header typeSystemIncluded(boolean f) {typeSystemIncluded = f; return this; }
    public Header seqVer(int v2) { assert (v2 >= 0 && v2 < 256); seqVersionNbr = (byte)v2; return this; }
    public Header v3() {isV3 = true; return this; }
    
    
    public void write(DataOutputStream dos) throws IOException {
      v = (!isCompressed && !isDelta) ? 1 : 0;
      if (isDelta) v |= 0x02;
      if (isCompressed) v |= 0x04;
      if (typeSystemIncluded) v |= 0x08;
      v |= (seqVersionNbr << 8);
      if (isV3) v |= 0x010000;
      
      
      byte[] uima = new byte[4];
      uima[0] = 85; // U
      uima[1] = 73; // I
      uima[2] = 77; // M
      uima[3] = 65; // A

      ByteBuffer buf = ByteBuffer.wrap(uima);
      int key = buf.asIntBuffer().get();

      dos.writeInt(key);
      dos.writeInt(v);
      
      if (isCompressed) {
        dos.writeInt(form6 ? 1 : 0);
      }
      
    }
    
    public boolean isDelta() {
      return isDelta;
    }
    public boolean isCompressed() {
      return isCompressed;
    }
    public boolean isV3style() {
      return isV3style;
    }
    public boolean isForm4() {
      return form4;
    }
    public boolean isForm6() {
      return form6;
    }
    public boolean isTypeSystemIncluded() {
      return typeSystemIncluded;
    }
    public byte getSeqVersionNbr() {
      return seqVersionNbr;
    }
    public boolean isV3() {
      return isV3;
    }

    
  }
  
  public static Header createHeader() {
    return new Header();
  }
  
  public static boolean isBinaryHeader(DataInputStream dis) {
    dis.mark(4);
    byte[] bytebuf = new byte[4];
    try {
      bytebuf[0] = dis.readByte(); // U
      bytebuf[1] = dis.readByte(); // I
      bytebuf[2] = dis.readByte(); // M
      bytebuf[3] = dis.readByte(); // A
      String s = new String(bytebuf, "UTF-8");
      return s.equals("UIMA") || s.equals("AMIU");
    } catch (IOException e) {
      return false;
    } finally {
      try {
        dis.reset();
      } catch (IOException e) {
        throw new UIMARuntimeException(e);
      }
    }
  }

  public static Header readHeader(DataInputStream dis) throws IOException {

    Header h = new Header();
    // key
    // determine if byte swap if needed based on key
    byte[] bytebuf = new byte[4];
    bytebuf[0] = dis.readByte(); // U
    bytebuf[1] = dis.readByte(); // I
    bytebuf[2] = dis.readByte(); // M
    bytebuf[3] = dis.readByte(); // A

    h.swap = (bytebuf[0] != 85);
    Reading r = new Reading(dis, h.swap);
    h.reading = r;

    int v = h.v = r.readInt();  // h.v for error message use
    
    h.isDelta = (v & 2) != 0;
    h.isCompressed = (v & 4) != 0;
    h.typeSystemIncluded = (v & 8) != 0;
    h.seqVersionNbr = (byte) ((v & 0xFF00) >> 8);
   
    if (h.isCompressed) {
      v = r.readInt();
      h.form4 = v == 0;
      h.form6 = v == 1;
    } 
    
    return h;
  }

  public static DataOutputStream maybeWrapToDataOutputStream(OutputStream os) {
    if (os instanceof DataOutputStream) {
      return (DataOutputStream) os;
    }
    return new DataOutputStream(os);
  }
  
  public static DataInputStream maybeWrapToDataInputStream(InputStream os) {
    if (os instanceof DataInputStream) {
      return (DataInputStream) os;
    }
    return new DataInputStream(os);
  }

  /** 
   * byte swapping reads of integer forms
   */
 
  public static class Reading {
    final DataInputStream dis;
    final boolean swap;
    
    Reading(DataInputStream dis, boolean swap) {
      this.dis = dis;
      this.swap = swap;
    }
    
    long readLong() throws IOException {
      long v = dis.readLong();
      return swap ? Long.reverseBytes(v) : v;
    }
    
    int readInt() throws IOException {
      int v = dis.readInt();
      return swap ? Integer.reverseBytes(v) : v;
    }
    
    short readShort() throws IOException {
      short v = dis.readShort();
      return swap ? Short.reverseBytes(v) : v;
    }

  }
  
}
