/*
 * Copyright (C) 2013 - 2022 ScalAgent Distributed Technologies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA.
 * 
 * Initial developer(s): ScalAgent Distributed Technologies
 * Contributor(s): 
 */
package fr.dyade.aaa.common.encoding;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.Serializable;

/**
 * Encodable object that wraps a string.
 * It also serves as a cache for the encoded string.
 */
@SuppressWarnings("serial")
public final class EncodedString implements Serializable, Encodable {
  private String string;
  
  private byte[] encodedString;
  
  public EncodedString() {}

  public EncodedString(String string) {
    super();
    this.string = string;
  }
  
  public String getString() {
    return string;
  }

  // Note (AF): This method seems to be never used
  public void writeTo(DataOutputStream os) throws IOException {
    if (encodedString == null) {
      encodedString = string.getBytes(EncodableHelper.charset);
    }
    os.writeInt(encodedString.length);
    os.write(encodedString);
  }
  
  // Note (AF): This method seems to be never used
  public void readFrom(DataInputStream is) throws IOException {
    int length = is.readInt();
    encodedString = new byte[length];
    is.readFully(encodedString);
    string = new String(encodedString, EncodableHelper.charset);
  }
  
  private void writeObject(java.io.ObjectOutputStream out) throws IOException {
    out.writeUTF(string);
  }

  private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
    string = in.readUTF();
  }

  @Override
  public int hashCode() {
    return string.hashCode();
  }

  @Override
  public boolean equals(Object obj) {
    if (obj instanceof EncodedString) {
      return ((EncodedString) obj).string.equals(string);
    } else {
      return string.equals(obj);
    }
  }

  @Override
  public String toString() {
    return string;
  }

  @Override
  public int getEncodableClassId() {
    return EncodableFactoryRepository.ENCODED_STRING_CLASS_ID;
  }

  @Override
  public int getEncodedSize() {
    return EncodableHelper.getStringEncodedSize(string);
  }

  @Override
  public void encode(Encoder encoder) throws Exception {
    if (encodedString == null) {
      encodedString = string.getBytes(EncodableHelper.charset);
    }
    encoder.encodeByteArray(encodedString);
  }

  @Override
  public void decode(Decoder decoder) throws Exception {
    encodedString = decoder.decodeByteArray();
    string = new String(encodedString, EncodableHelper.charset);
  }
  
  public static class Factory implements EncodableFactory {
    public Encodable createEncodable() {
      return new EncodedString();
    }
  }
}
