
/* ====================================================================
   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.poi.ddf;

import java.io.PrintWriter;
import java.util.Collections;
import java.util.List;

import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;

/**
 * The base abstract record from which all escher records are defined.  Subclasses will need
 * to define methods for serialization/deserialization and for determining the record size.
 */
public abstract class EscherRecord implements Cloneable {
    private static final BitField fInstance = BitFieldFactory.getInstance(0xfff0);
    private static final BitField fVersion = BitFieldFactory.getInstance(0x000f);

    private short _options;
    private short _recordId;

    /**
     * Create a new instance
     */
    public EscherRecord() {
        // fields uninitialised
    }

    /**
     * Delegates to fillFields(byte[], int, EscherRecordFactory)
     *
     * @param data they bytes to serialize from
     * @param f the escher record factory
     * @return The number of bytes written.
     *
     * @see #fillFields(byte[], int, org.apache.poi.ddf.EscherRecordFactory)
     */
    protected int fillFields( byte[] data, EscherRecordFactory f )
    {
        return fillFields( data, 0, f );
    }

    /**
     * The contract of this method is to deserialize an escher record including
     * it's children.
     *
     * @param data      The byte array containing the serialized escher
     *                  records.
     * @param offset    The offset into the byte array.
     * @param recordFactory     A factory for creating new escher records.
     * @return          The number of bytes written.
     */
    public abstract int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory );

    /**
     * Reads the 8 byte header information and populates the <code>options</code>
     * and <code>recordId</code> records.
     *
     * @param data      the byte array to read from
     * @param offset    the offset to start reading from
     * @return          the number of bytes remaining in this record.  This
     *                  may include the children if this is a container.
     */
    protected int readHeader( byte[] data, int offset ) {
        _options = LittleEndian.getShort( data, offset );
        _recordId = LittleEndian.getShort( data, offset + 2 );
        return LittleEndian.getInt( data, offset + 4 );
    }

    /**
     * Read the options field from header and return instance part of it.
     * @param data      the byte array to read from
     * @param offset    the offset to start reading from
     * @return          value of instance part of options field
     */
    protected static short readInstance( byte data[], int offset ) {
        final short options = LittleEndian.getShort( data, offset );
        return fInstance.getShortValue( options );
    }

    /**
     * Determine whether this is a container record by inspecting the option field.
     *
     * @return  true is this is a container field.
     */
    public boolean isContainerRecord() {
        return getVersion() == (short)0x000f;
    }

    /**
     * Note that <code>options</code> is an internal field.
     * Use {@link #setInstance(short)} ()} and {@link #setVersion(short)} ()} to set the actual fields.
     *
     * @return The options field for this record. All records have one.
     */
    @Internal
    public short getOptions()
    {
        return _options;
    }

    /**
     * Set the options this this record. Container records should have the
     * last nibble set to 0xF.<p>
     *
     * Note that {@code options} is an internal field.
     * Use {@link #getInstance()} and {@link #getVersion()} to access actual fields.
     *
     * @param options the record options
     */
    @Internal
    public void setOptions( short options ) {
        // call to handle correct/incorrect values
        setVersion( fVersion.getShortValue( options ) );
        setInstance( fInstance.getShortValue( options ) );
        _options = options;
    }

    /**
     * Serializes to a new byte array.  This is done by delegating to
     * serialize(int, byte[]);
     *
     * @return  the serialized record.
     * @see #serialize(int, byte[])
     */
    public byte[] serialize()
    {
        byte[] retval = new byte[getRecordSize()];

        serialize( 0, retval );
        return retval;
    }

    /**
     * Serializes to an existing byte array without serialization listener.
     * This is done by delegating to serialize(int, byte[], EscherSerializationListener).
     *
     * @param offset    the offset within the data byte array.
     * @param data      the data array to serialize to.
     * @return          The number of bytes written.
     *
     * @see #serialize(int, byte[], org.apache.poi.ddf.EscherSerializationListener)
     */
    public int serialize( int offset, byte[] data)
    {
        return serialize( offset, data, new NullEscherSerializationListener() );
    }

    /**
     * Serializes the record to an existing byte array.
     *
     * @param offset    the offset within the byte array
     * @param data      the data array to serialize to
     * @param listener  a listener for begin and end serialization events.  This
     *                  is useful because the serialization is
     *                  hierarchical/recursive and sometimes you need to be able
     *                  break into that.
     * @return the number of bytes written.
     */
    public abstract int serialize( int offset, byte[] data, EscherSerializationListener listener );

    /**
     * Subclasses should effeciently return the number of bytes required to
     * serialize the record.
     *
     * @return  number of bytes
     */
    abstract public int getRecordSize();

    /**
     * Return the current record id.
     *
     * @return  The 16 bit record id.
     */
    public short getRecordId() {
        return _recordId;
    }

    /**
     * Sets the record id for this record.
     *
     * @param recordId the record id
     */
    public void setRecordId( short recordId ) {
        _recordId = recordId;
    }

    /**
     * @return  Returns the children of this record.  By default this will
     *          be an empty list.  EscherCotainerRecord is the only record
     *          that may contain children.
     *
     * @see EscherContainerRecord
     */
    public List<EscherRecord> getChildRecords() { return Collections.emptyList(); }

    /**
     * Sets the child records for this record.  By default this will throw
     * an exception as only EscherContainerRecords may have children.
     *
     * @param childRecords  Not used in base implementation.
     */
    public void setChildRecords(List<EscherRecord> childRecords) {
        throw new UnsupportedOperationException("This record does not support child records.");
    }

    /**
     * Escher records may need to be clonable in the future.
     *
     * @return the cloned object
     *
     * @throws CloneNotSupportedException if the subclass hasn't implemented {@link Cloneable}
     */
    @Override
    public EscherRecord clone() throws CloneNotSupportedException {
        return (EscherRecord)super.clone();
    }

    /**
     * Returns the indexed child record.
     *
     * @param index the index of the child within the child records
     * @return the indexed child record
     */
    public EscherRecord getChild( int index ) {
        return getChildRecords().get(index);
    }

    /**
     * The display methods allows escher variables to print the record names
     * according to their hierarchy.
     *
     * @param w         The print writer to output to.
     * @param indent    The current indent level.
     */
    public void display(PrintWriter w, int indent)
    {
        for (int i = 0; i < indent * 4; i++) {
            w.print(' ');
        }
        w.println(getRecordName());
    }

    /**
     * Subclasses should return the short name for this escher record.
     *
     * @return the short name for this escher record
     */
    public abstract String getRecordName();

    /**
     * Returns the instance part of the option record.
     *
     * @return The instance part of the record
     */
    public short getInstance()
    {
        return fInstance.getShortValue( _options );
    }

    /**
     * Sets the instance part of record
     *
     * @param value instance part value
     */
    public void setInstance( short value )
    {
        _options = fInstance.setShortValue( _options, value );
    }

    /**
     * Returns the version part of the option record.
     *
     * @return The version part of the option record
     */
    public short getVersion()
    {
        return fVersion.getShortValue( _options );
    }

    /**
     * Sets the version part of record
     *
     * @param value version part value
     */
    public void setVersion( short value )
    {
        _options = fVersion.setShortValue( _options, value );
    }

    public String toXml(){
        return toXml("");
    }

    /**
     * @param tab - each children must be indented right relative to its parent
     * @return xml representation of this record
     */
    public final String toXml(String tab){
        final String nl = System.getProperty( "line.separator" );
        String clsNm = getClass().getSimpleName();
        StringBuilder sb = new StringBuilder(1000);
        sb.append(tab).append("<").append(clsNm)
          .append(" recordId=\"0x").append(HexDump.toHex(getRecordId()))
          .append("\" version=\"0x").append(HexDump.toHex(getVersion()))
          .append("\" instance=\"0x").append(HexDump.toHex(getInstance()))
          .append("\" options=\"0x").append(HexDump.toHex(getOptions()))
          .append("\" recordSize=\"").append(getRecordSize());
        Object[][] attrList = getAttributeMap();
        if (attrList == null || attrList.length == 0) {
            sb.append("\" />").append(nl);
        } else {
            sb.append("\">").append(nl);
            String childTab = tab+"   ";
            for (Object[] attrs : attrList) {
                String tagName = capitalizeAndTrim((String)attrs[0]);
                boolean hasValue = false;
                boolean lastChildComplex = false;
                for (int i=0; i<attrs.length; i+=2) {
                    Object value = attrs[i+1];
                    if (value == null) {
                        // ignore null values
                        continue;
                    }
                    if (!hasValue) {
                        // only add tagname, when there was a value
                        sb.append(childTab).append("<").append(tagName).append(">");
                    }
                    // add names for optional attributes
                    String optName = capitalizeAndTrim((String)attrs[i+0]);
                    if (i>0) {
                        sb.append(nl).append(childTab).append("  <").append(optName).append(">");
                    }
                    lastChildComplex = appendValue(sb, value, true, childTab);
                    if (i>0) {
                        sb.append(nl).append(childTab).append("  </").append(optName).append(">");
                    }
                    hasValue = true;
                }
                if (hasValue) {
                    if (lastChildComplex) {
                        sb.append(nl).append(childTab);
                    }
                    sb.append("</").append(tagName).append(">").append(nl);
                }
            }
            sb.append(tab).append("</").append(clsNm).append(">");
        }
        return sb.toString();
    }

    @Override
    public final String toString() {
        final String nl = System.getProperty( "line.separator" );
        StringBuilder sb = new StringBuilder(1000);
        sb.append(getClass().getName()).append(" (").append(getRecordName()).append("):").append(nl)
          .append("  RecordId: 0x").append(HexDump.toHex( getRecordId() )).append(nl)
          .append("  Version: 0x").append(HexDump.toHex( getVersion() )).append(nl)
          .append("  Instance: 0x").append(HexDump.toHex( getInstance() )).append(nl)
          .append("  Options: 0x").append(HexDump.toHex( getOptions() )).append(nl)
          .append("  Record Size: ").append( getRecordSize() );

        Object[][] attrList = getAttributeMap();
        if (attrList != null && attrList.length > 0) {
            String childTab = "  ";
            for (Object[] attrs : attrList) {
                for (int i=0; i<attrs.length; i+=2) {
                    Object value = attrs[i+1];
                    if (value == null) {
                        // ignore null values
                        continue;
                    }
                    String name = (String)attrs[i+0];
                    sb.append(nl).append(childTab).append(name).append(": ");
                    appendValue(sb, value, false, childTab);
                }
            }
        }

        return sb.toString();
    }
    
    /**
     * @return true, if value was a complex record, false otherwise
     */
    private static boolean appendValue(StringBuilder sb, Object value, boolean toXML, String childTab) {
        final String nl = System.getProperty( "line.separator" );
        boolean isComplex = false;
        if (value instanceof String) {
            if (toXML) {
                escapeXML((String)value, sb);
            } else {
                sb.append((String)value);
            }
        } else if (value instanceof Byte) {
            sb.append("0x").append(HexDump.toHex((Byte)value));
        } else if (value instanceof Short) {
            sb.append("0x").append(HexDump.toHex((Short)value));
        } else if (value instanceof Integer) {
            sb.append("0x").append(HexDump.toHex((Integer)value));
        } else if (value instanceof byte[]) {
            sb.append(nl).append(HexDump.toHex((byte[])value, 32).replaceAll("(?m)^",childTab+"   "));
        } else if (value instanceof Boolean) {
            sb.append(((Boolean)value).booleanValue());
        } else if (value instanceof EscherRecord) {
            EscherRecord er = (EscherRecord)value;
            if (toXML) {
                sb.append(nl).append(er.toXml(childTab+"    "));
            } else {
                sb.append(er.toString().replaceAll("(?m)^",childTab));
            }
            isComplex = true;
        } else if (value instanceof EscherProperty) {
            EscherProperty ep = (EscherProperty)value;
            if (toXML) {
                sb.append(nl).append(ep.toXml(childTab+"  "));
            } else {
                sb.append(ep.toString().replaceAll("(?m)^",childTab));
            }
            isComplex = true;
        } else {
            throw new IllegalArgumentException("unknown attribute type "+value.getClass().getSimpleName());
        }
        return isComplex;
    }

    /**
     * For the purpose of providing toString() and toXml() a subclass can either override those methods
     * or provide a Object[][] array in the form {@code { { "Attribute Name (Header)", value, "optional attribute", value }, ... } }.<p>
     *
     * Null values won't be printed.<p>
     *
     * The attributes record, version, instance, options must not be returned.
     *
     * @return the attribute map
     * 
     * @since POI 3.17-beta2
     */
    @Internal
    protected abstract Object[][] getAttributeMap();

    private static String capitalizeAndTrim(final String str) {
        if (str == null || str.length() == 0) {
            return str;
        }

        StringBuilder sb = new StringBuilder(str.length());
        boolean capitalizeNext = true;
        for (char ch : str.toCharArray()) {
            if (!Character.isLetterOrDigit(ch)) {
                capitalizeNext = true;
                continue;
            }

            if (capitalizeNext) {
                if (!Character.isLetter(ch)) {
                    sb.append('_');
                } else {
                    ch = Character.toTitleCase(ch);
                }
                capitalizeNext = false;
            }
            sb.append(ch);
        }

        return sb.toString();
    }

    private static void escapeXML(String s, StringBuilder out) {
        if (s == null || s.isEmpty()) {
            return;
        }
        for (char c : s.toCharArray()) {
            if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') {
                out.append("&#");
                out.append((int) c);
                out.append(';');
            } else {
                out.append(c);
            }
        }
    }
}