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

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.LinkedHashMap;

/** Base class for metadata. */
public class MetaData<T extends MetaData> extends LinkedHashMap<String,byte[]> {

  static final String RESERVED_KEY_PREFIX = "trevni.";

  static final String CODEC_KEY = RESERVED_KEY_PREFIX + "codec";
  static final String CHECKSUM_KEY = RESERVED_KEY_PREFIX + "checksum";

  public static final Charset UTF8 = Charset.forName("UTF-8");

  private MetaData<?> defaults;

  void setDefaults(MetaData defaults) { this.defaults = defaults; }

  /** Return the compression codec name. */
  public String getCodec() { return getString(CODEC_KEY); }

  /** Set the compression codec name. */
  public T setCodec(String codec) {
    setReserved(CODEC_KEY, codec);
    return (T)this;
  }

  /** Return the checksum algorithm name. */
  public String getChecksum() { return getString(CHECKSUM_KEY); }

  /** Set the checksum algorithm name. */
  public T setChecksum(String checksum) {
    setReserved(CHECKSUM_KEY, checksum);
    return (T)this;
  }

  /** Return the value of a metadata property as a String. */
  public String getString(String key) {
    byte[] value = get(key);
    if (value == null && defaults != null)
      value = defaults.get(key);
    if (value == null)
      return null;
    return new String(value, UTF8);
  }

  /** Return the value of a metadata property as a long. */
  public long getLong(String key) {
    return Long.parseLong(getString(key));
  }

  /** Return true iff a key has any value, false if it is not present. */
  public boolean getBoolean(String key) {
    return get(key) != null;
  }

  /** Set a metadata property to a binary value. */
  public T set(String key, byte[] value) {
    if (isReserved(key)) {
      throw new TrevniRuntimeException("Cannot set reserved key: " + key);
    }
    put(key, value);
    return (T)this;
  }

  /** Test if a metadata key is reserved. */
  public static boolean isReserved(String key) {
    return key.startsWith(RESERVED_KEY_PREFIX);
  }

  /** Set a metadata property to a String value. */
  public T set(String key, String value) {
    return set(key, value.getBytes(UTF8));
  }

  T setReserved(String key, String value) {
    put(key, value.getBytes(UTF8));
    return (T)this;
  }

  T setReservedBoolean(String key, boolean value) {
    if (value)
      setReserved(key, "");
    else
      remove(key);
    return (T)this;
  }

  /** Set a metadata property to a long value. */
  public T set(String key, long value) {
    return set(key, Long.toString(value));
  }

  void write(OutputBuffer out) throws IOException {
    out.writeInt(size());
    for (Map.Entry<String,byte[]> e : entrySet()) {
      out.writeString(e.getKey());
      out.writeBytes(e.getValue());
    }
  }

  static void read(InputBuffer in, MetaData<?> metaData) throws IOException {
    int size = in.readInt();
    for (int i = 0; i < size; i++)
      metaData.put(in.readString(), in.readBytes());
  }

  @Override public String toString() {
    StringBuffer buffer = new StringBuffer();
    buffer.append("{ ");
    for (Map.Entry<String,byte[]> e : entrySet()) {
      buffer.append(e.getKey());
      buffer.append("=");
      try {
        buffer.append(new String(e.getValue(), "ISO-8859-1"));
      } catch (java.io.UnsupportedEncodingException error) {
        throw new TrevniRuntimeException(error);
      }
      buffer.append(" ");
    }
    buffer.append("}");
    return buffer.toString();
  }

}
