/*
 *  ====================================================================
 *    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.ByteArrayInputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;

import org.apache.poi.util.GenericRecordUtil;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.RecordFormatException;
import org.apache.poi.util.StringUtil;

/**
 * DConRef records specify a range in a workbook (internal or external) that serves as a data source
 * for pivot tables or data consolidation.
 *
 * Represents a <code>DConRef</code> Structure
 * <a href="http://msdn.microsoft.com/en-us/library/dd923854(office.12).aspx">[MS-XLS s.
 * 2.4.86]</a>, and the contained <code>DConFile</code> structure
 * <a href="http://msdn.microsoft.com/en-us/library/dd950157(office.12).aspx">
 * [MS-XLS s. 2.5.69]</a>. This in turn contains a <code>XLUnicodeStringNoCch</code>
 * <a href="http://msdn.microsoft.com/en-us/library/dd910585(office.12).aspx">
 * [MS-XLS s. 2.5.296]</a>.
 *
 * <pre>
 *         _______________________________
 *        |          DConRef              |
 *(bytes) +-+-+-+-+-+-+-+-+-+-+...+-+-+-+-+
 *        |    ref    |cch|  stFile   | un|
 *        +-+-+-+-+-+-+-+-+-+-+...+-+-+-+-+
 *                              |
 *                     _________|_____________________
 *                    |DConFile / XLUnicodeStringNoCch|
 *                    +-+-+-+-+-+-+-+-+-+-+-+...+-+-+-+
 *             (bits) |h|   reserved  |      rgb      |
 *                    +-+-+-+-+-+-+-+-+-+-+-+...+-+-+-+
 * </pre>
 * Where
 * <ul>
 * <li><code>DConFile.h = 0x00</code> if the characters in<code>rgb</code> are single byte, and
 * <code>DConFile.h = 0x01</code> if they are double byte.<p>
 * If they are double byte, then
 * <ul>
 * <li> If it exists, the length of <code>DConRef.un = 2</code>. Otherwise it is 1.
 * <li> The length of <code>DConFile.rgb = (2 * DConRef.cch)</code>. Otherwise it is equal to
 * <code>DConRef.cch</code>.
 * </ul>
 * <li><code>DConRef.rgb</code> starts with <code>0x01</code> if it is an external reference,
 * and with <code>0x02</code> if it is a self-reference.
 * </ul>
 *
 * At the moment this class is read-only.
 */
public class DConRefRecord extends StandardRecord {

    //arbitrarily selected; may need to increase
    private static final int MAX_RECORD_LENGTH = 100_000;

    /**
     * The id of the record type,
     * <code>sid = {@value}</code>
     */
    public static final short sid = 0x0051;
    /**
     * A RefU structure specifying the range of cells if this record is part of an SXTBL.
     * <a href="http://msdn.microsoft.com/en-us/library/dd920420(office.12).aspx">
     * [MS XLS s.2.5.211]</a>
     */
    private int firstRow, lastRow, firstCol, lastCol;
    /**
     * the number of chars in the link
     */
    private int charCount;
    /**
     * the type of characters (single or double byte)
     */
    private int charType;
    /**
     * The link's path string. This is the <code>rgb</code> field of a
     * <code>XLUnicodeStringNoCch</code>. Therefore it will contain at least one leading special
     * character (0x01 or 0x02) and probably other ones.<p>
     * @see <A href="http://msdn.microsoft.com/en-us/library/dd923491(office.12).aspx">
     * DConFile [MS-XLS s. 2.5.77]</A> and
     * <A href="http://msdn.microsoft.com/en-us/library/dd950157(office.12).aspx">
     * VirtualPath [MS-XLS s. 2.5.69]</a>
     * <p>
     */
    private byte[] path;
    /**
     * unused bits at the end, must be set to 0.
     */
    private byte[] _unused;

    public DConRefRecord(DConRefRecord other) {
        super(other);
        firstCol = other.firstCol;
        firstRow = other.firstRow;
        lastCol = other.lastCol;
        lastRow = other.lastRow;
        charCount = other.charCount;
        charType = other.charType;
        path = (other.path == null) ? null : other.path.clone();
        _unused = (other._unused == null) ? null : other._unused.clone();
    }

    /**
     * Read constructor.
     *
     * @param data byte array containing a DConRef Record, including the header.
     */
    public DConRefRecord(byte[] data) {
        this(bytesToRIStream(data));
    }

    /**
     * Read Constructor.
     *
     * @param inStream RecordInputStream containing a DConRefRecord structure.
     */
    public DConRefRecord(RecordInputStream inStream) {
        if (inStream.getSid() != sid) {
            throw new RecordFormatException("Wrong sid: " + inStream.getSid());
        }

        firstRow = inStream.readUShort();
        lastRow = inStream.readUShort();
        firstCol = inStream.readUByte();
        lastCol = inStream.readUByte();

        charCount = inStream.readUShort();

        // 7 bits reserved + 1 bit type - first bit only
        charType = inStream.readUByte() & 0x01;

        // bytelength is the length of the string in bytes, which depends on whether the string is
        // made of single- or double-byte chars. This is given by charType, which equals 0 if
        // single-byte, 1 if double-byte.
        final int byteLength = charCount * (charType + 1);

        path = IOUtils.safelyAllocate(byteLength, MAX_RECORD_LENGTH);
        inStream.readFully(path);

        // If it's a self reference, the last one or two bytes (depending on char type) are the
        // unused field. Not sure If i need to bother with this...
        if (path[0] == 0x02) {
            _unused = inStream.readRemainder();
        }
    }

    /*
     * assuming this wants the number of bytes returned by {@link serialize(LittleEndianOutput)},
     * that is, (length - 4).
     */
    @Override
    protected int getDataSize()
    {
        int sz = 9 + path.length;
        if (path[0] == 0x02)
            sz += _unused.length;
        return sz;
    }

    @Override
    protected void serialize(LittleEndianOutput out)
    {
        out.writeShort(firstRow);
        out.writeShort(lastRow);
        out.writeByte(firstCol);
        out.writeByte(lastCol);
        out.writeShort(charCount);
        out.writeByte(charType);
        out.write(path);
        if (path[0] == 0x02)
            out.write(_unused);
    }

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

    /**
     * @return The first column of the range.
     */
    public int getFirstColumn()
    {
        return firstCol;
    }

    /**
     * @return The first row of the range.
     */
    public int getFirstRow()
    {
        return firstRow;
    }

    /**
     * @return The last column of the range.
     */
    public int getLastColumn()
    {
        return lastCol;
    }

    /**
     * @return The last row of the range.
     */
    public int getLastRow()
    {
        return lastRow;
    }

    /**
     *
     * @return raw path byte array.
     */
    public byte[] getPath()
    {
        return Arrays.copyOf(path, path.length);
    }

    /**
     * @return the link's path, with the special characters stripped/replaced. May be null.
     * See MS-XLS 2.5.277 (VirtualPath)
     */
    public String getReadablePath()
    {
        if (path != null)
        {
            //all of the path strings start with either 0x02 or 0x01 followed by zero or
            //more of 0x01..0x08
            int offset = 1;
            while (offset < path.length && path[offset] < 0x20) {
                offset++;
            }
            String out = new String(Arrays.copyOfRange(path, offset, path.length), StringUtil.UTF8);
            //UNC paths have \u0003 chars as path separators.
            out = out.replaceAll("\u0003", "/");
            return out;
        }
        return null;
    }

    /**
     * Checks if the data source in this reference record is external to this sheet or internal.
     *
     * @return true iff this is an external reference.
     */
    public boolean isExternalRef()
    {
        return path[0] == 0x01;
    }

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

    private static RecordInputStream bytesToRIStream(byte[] data) {
        RecordInputStream ric = new RecordInputStream(new ByteArrayInputStream(data));
        ric.nextRecord();
        return ric;
    }

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

    @Override
    public Map<String, Supplier<?>> getGenericProperties() {
        return GenericRecordUtil.getGenericProperties(
            "firstRow", this::getFirstRow,
            "lastRow", this::getLastRow,
            "firstColumn", this::getFirstColumn,
            "lastColumn", this::getLastColumn,
            "charCount", () -> charCount,
            "charType", () -> charType,
            "path", this::getReadablePath
        );
    }
}
