/* ====================================================================
   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.hssf.record;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

import org.apache.poi.util.GenericRecordUtil;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianByteArrayInputStream;
import org.apache.poi.util.LittleEndianByteArrayOutputStream;
import org.apache.poi.util.RecordFormatException;

/**
 * OBJRECORD (0x005D)<p>
 *
 * The obj record is used to hold various graphic objects and controls.
 */
public final class ObjRecord extends Record {
    public static final short sid = 0x005D;

    private static final int NORMAL_PAD_ALIGNMENT = 2;
    private static int MAX_PAD_ALIGNMENT = 4;

    private final List<SubRecord> subrecords = new ArrayList<>();
    /**
     * used when POI has no idea what is going on
     */
    private final byte[] _uninterpretedData;
    /**
     * Excel seems to tolerate padding to quad or double byte length
     */
    private boolean _isPaddedToQuadByteMultiple;

    //00000000 15 00 12 00 01 00 01 00 11 60 00 00 00 00 00 0D .........`......
    //00000010 26 01 00 00 00 00 00 00 00 00                   &.........


    public ObjRecord() {
        // TODO - ensure 2 sub-records (ftCmo 15h, and ftEnd 00h) are always created
        _uninterpretedData = null;
    }

    public ObjRecord(ObjRecord other) {
        other.subrecords.stream().map(SubRecord::copy).forEach(subrecords::add);
        _uninterpretedData = (other._uninterpretedData == null) ? null : other._uninterpretedData.clone();
        _isPaddedToQuadByteMultiple = other._isPaddedToQuadByteMultiple;
    }

    public ObjRecord(RecordInputStream in) {
        // TODO - problems with OBJ sub-records stream
        // MS spec says first sub-record is always CommonObjectDataSubRecord,
        // and last is always EndSubRecord. OOO spec does not mention ObjRecord(0x005D).
        // Existing POI test data seems to violate that rule. Some test data
        // seems to contain garbage, and a crash is only averted by stopping at
                // what looks like the 'EndSubRecord'

        // Check if this can be continued, if so then the
        // following wont work properly
        byte[] subRecordData = in.readRemainder();
        if (LittleEndian.getUShort(subRecordData, 0) != CommonObjectDataSubRecord.sid) {
            // seems to occur in just one junit on "OddStyleRecord.xls" (file created by CrystalReports)
            // Excel tolerates the funny ObjRecord, and replaces it with a corrected version
            // The exact logic/reasoning is not yet understood
            _uninterpretedData = subRecordData;
            return;
        }

        //YK: files produced by OO violate the condition below
        /*
        if (subRecordData.length % 2 != 0) {
            String msg = "Unexpected length of subRecordData : " + HexDump.toHex(subRecordData);
            throw new RecordFormatException(msg);
        }
        */

        LittleEndianByteArrayInputStream subRecStream = new LittleEndianByteArrayInputStream(subRecordData);
        CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord)SubRecord.createSubRecord(subRecStream, 0);
        subrecords.add(cmo);
        while (true) {
            SubRecord subRecord = SubRecord.createSubRecord(subRecStream, cmo.getObjectType());
            subrecords.add(subRecord);
            if (subRecord.isTerminating()) {
                break;
            }
        }
        final int nRemainingBytes = subRecordData.length-subRecStream.getReadIndex();
        if (nRemainingBytes > 0) {
            // At present (Oct-2008), most unit test samples have (subRecordData.length % 2 == 0)
            _isPaddedToQuadByteMultiple = subRecordData.length % MAX_PAD_ALIGNMENT == 0;
            if (nRemainingBytes >= (_isPaddedToQuadByteMultiple ? MAX_PAD_ALIGNMENT : NORMAL_PAD_ALIGNMENT)) {
                if (!canPaddingBeDiscarded(subRecordData, nRemainingBytes)) {
                    String msg = "Leftover " + nRemainingBytes
                        + " bytes in subrecord data " + HexDump.toHex(subRecordData);
                    throw new RecordFormatException(msg);
                }
                _isPaddedToQuadByteMultiple = false;
            }

        } else {
            _isPaddedToQuadByteMultiple = false;
        }
        _uninterpretedData = null;
    }

    /**
     * Some XLS files have ObjRecords with nearly 8Kb of excessive padding. These were probably
     * written by a version of POI (around 3.1) which incorrectly interpreted the second short of
     * the ftLbs subrecord (0x1FEE) as a length, and read that many bytes as padding (other bugs
     * helped allow this to occur).
     *
     * Excel reads files with this excessive padding OK, truncating the over-sized ObjRecord back
     * to the its proper size.  POI does the same.
     */
    private static boolean canPaddingBeDiscarded(byte[] data, int nRemainingBytes) {
        // make sure none of the padding looks important
        for(int i=data.length-nRemainingBytes; i<data.length; i++) {
            if (data[i] != 0x00) {
                return false;
            }
        }
        return true;
    }

    @Override
    public int getRecordSize() {
        if (_uninterpretedData != null) {
            return _uninterpretedData.length + 4;
        }
        int size = 0;
        for (SubRecord record : subrecords) {
            size += record.getDataSize()+4;
        }
        if (_isPaddedToQuadByteMultiple) {
            while (size % MAX_PAD_ALIGNMENT != 0) {
                size++;
            }
        } else {
            while (size % NORMAL_PAD_ALIGNMENT != 0) {
                size++;
            }
        }
        return size + 4;
    }

    @Override
    public int serialize(int offset, byte[] data) {
        int recSize = getRecordSize();
        int dataSize = recSize - 4;

        try (LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize)) { // NOSONAR
            out.writeShort(sid);
            out.writeShort(dataSize);

            if (_uninterpretedData == null) {

                for (int i = 0; i < subrecords.size(); i++) {
                    SubRecord record = subrecords.get(i);
                    record.serialize(out);
                }
                int expectedEndIx = offset + dataSize;
                // padding
                while (out.getWriteIndex() < expectedEndIx) {
                    out.writeByte(0);
                }
            } else {
                out.write(_uninterpretedData);
            }
        } catch (IOException ioe) {
            // should never happen in practice
            throw new IllegalStateException(ioe);
        }
        return recSize;
    }

    @Override
    public short getSid() {
        return sid;
    }

        // FIXME: return Collections.unmodifiableList?
    public List<SubRecord> getSubRecords() {
        return subrecords;
    }

    public void clearSubRecords() {
        subrecords.clear();
    }

    public void addSubRecord(int index, SubRecord element) {
        subrecords.add(index, element);
    }

    public boolean addSubRecord(SubRecord o) {
        return subrecords.add(o);
    }

    @Override
    public ObjRecord copy() {
        return new ObjRecord(this);
    }

    @Override
    public HSSFRecordTypes getGenericRecordType() {
        return HSSFRecordTypes.OBJ;
    }

    @Override
    public Map<String, Supplier<?>> getGenericProperties() {
        return GenericRecordUtil.getGenericProperties(
            "uninterpretedData", () -> _uninterpretedData,
            "paddedToQuadByteMultiple", () -> _isPaddedToQuadByteMultiple
        );
    }

    @Override
    public List<SubRecord> getGenericChildren() {
        return getSubRecords();
    }
}
