/* ====================================================================
   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 static org.apache.logging.log4j.util.Unbox.box;
import static org.apache.poi.hpsf.ClassIDPredefined.FILE_MONIKER;
import static org.apache.poi.hpsf.ClassIDPredefined.STD_MONIKER;
import static org.apache.poi.hpsf.ClassIDPredefined.URL_MONIKER;
import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
import static org.apache.poi.util.HexDump.toHex;

import java.util.Map;
import java.util.function.Supplier;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hpsf.ClassID;
import org.apache.poi.hpsf.ClassIDPredefined;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.GenericRecordUtil;
import org.apache.poi.util.HexRead;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.RecordFormatException;
import org.apache.poi.util.StringUtil;

/**
 * The <code>HyperlinkRecord</code> (0x01B8) wraps an HLINK-record
 *  from the Excel-97 format.
 * Supports only external links for now (eg http://)
 */
public final class HyperlinkRecord extends StandardRecord {
    public static final short sid = 0x01B8;
    private static final Logger LOG = LogManager.getLogger(HyperlinkRecord.class);
    //arbitrarily selected; may need to increase
    private static final int MAX_RECORD_LENGTH = 100_000;


    /*
     * Link flags
     */
    static final int HLINK_URL    = 0x01;  // File link or URL.
    static final int HLINK_ABS    = 0x02;  // Absolute path.
    static final int HLINK_LABEL  = 0x14;  // Has label/description.
    /** Place in worksheet. If set, the {@link #_textMark} field will be present */
    static final int HLINK_PLACE  = 0x08;
    private static final int  HLINK_TARGET_FRAME  = 0x80;  // has 'target frame'
    private static final int  HLINK_UNC_PATH  = 0x100;  // has UNC path

    /** expected Tail of a URL link */
    private static final byte[] URL_TAIL  = HexRead.readFromString("79 58 81 F4  3B 1D 7F 48   AF 2C 82 5D  C4 85 27 63   00 00 00 00  A5 AB 00 00");
    /** expected Tail of a file link */
    private static final byte[] FILE_TAIL = HexRead.readFromString("FF FF AD DE  00 00 00 00   00 00 00 00  00 00 00 00   00 00 00 00  00 00 00 00");

    private static final int TAIL_SIZE = FILE_TAIL.length;

    /** cell range of this hyperlink */
    private CellRangeAddress _range;

    /** 16-byte GUID */
    private ClassID _guid;
    /** Some sort of options for file links. */
    private int _fileOpts;
    /** Link options. Can include any of HLINK_* flags. */
    private int _linkOpts;
    /** Test label */
    private String _label;

    private String _targetFrame;
    /** Moniker. Makes sense only for URL and file links */
    private ClassID _moniker;
    /** in 8:3 DOS format No Unicode string header,
     * always 8-bit characters, zero-terminated */
    private String _shortFilename;
    /** Link */
    private String _address;
    /**
     * Text describing a place in document.  In Excel UI, this is appended to the
     * address, (after a '#' delimiter).<br>
     * This field is optional.  If present, the {@link #HLINK_PLACE} must be set.
     */
    private String _textMark;

    private byte[] _uninterpretedTail;

    /**
     * Create a new hyperlink
     */
    public HyperlinkRecord() {}


    public HyperlinkRecord(HyperlinkRecord other) {
        super(other);
        _range = (other._range == null) ? null : other._range.copy();
        _guid = (other._guid == null) ? null : other._guid.copy();
        _fileOpts = other._fileOpts;
        _linkOpts = other._linkOpts;
        _label = other._label;
        _targetFrame = other._targetFrame;
        _moniker = (other._moniker == null) ? null : other._moniker.copy();
        _shortFilename = other._shortFilename;
        _address = other._address;
        _textMark = other._textMark;
        _uninterpretedTail = (other._uninterpretedTail == null) ? null : other._uninterpretedTail.clone();
    }


    /**
     * @return the 0-based column of the first cell that contains this hyperlink
     */
    public int getFirstColumn() {
        return _range.getFirstColumn();
    }

    /**
     * Set the first column (zero-based) of the range that contains this hyperlink
     *
     * @param firstCol the first column (zero-based)
     */
    public void setFirstColumn(int firstCol) {
        _range.setFirstColumn(firstCol);
    }

    /**
     * @return the 0-based column of the last cell that contains this hyperlink
     */
    public int getLastColumn() {
        return _range.getLastColumn();
    }

    /**
     * Set the last column (zero-based) of the range that contains this hyperlink
     *
     * @param lastCol the last column (zero-based)
     */
    public void setLastColumn(int lastCol) {
        _range.setLastColumn(lastCol);
    }

    /**
     * @return the 0-based row of the first cell that contains this hyperlink
     */
    public int getFirstRow() {
        return _range.getFirstRow();
    }

    /**
     * Set the first row (zero-based) of the range that contains this hyperlink
     *
     * @param firstRow the first row (zero-based)
     */
    public void setFirstRow(int firstRow) {
        _range.setFirstRow(firstRow);
    }

    /**
     * @return the 0-based row of the last cell that contains this hyperlink
     */
    public int getLastRow() {
        return _range.getLastRow();
    }

    /**
     * Set the last row (zero-based) of the range that contains this hyperlink
     *
     * @param lastRow the last row (zero-based)
     */
    public void setLastRow(int lastRow) {
        _range.setLastRow(lastRow);
    }

    /**
     * @return 16-byte guid identifier Seems to always equal {@link ClassIDPredefined#STD_MONIKER}
     */
    ClassID getGuid() {
        return _guid;
    }

    /**
     * @return 16-byte moniker
     */
    ClassID getMoniker()
    {
        return _moniker;
    }

    private static String cleanString(String s) {
        if (s == null) {
            return null;
        }
        int idx = s.indexOf('\u0000');
        if (idx < 0) {
            return s;
        }
        return s.substring(0, idx);
    }
    private static String appendNullTerm(String s) {
        if (s == null) {
            return null;
        }
        return s + '\u0000';
    }

    /**
     * Return text label for this hyperlink
     *
     * @return  text to display
     */
    public String getLabel() {
        return cleanString(_label);
    }

    /**
     * Sets text label for this hyperlink
     *
     * @param label text label for this hyperlink
     */
    public void setLabel(String label) {
        _label = appendNullTerm(label);
    }
    public String getTargetFrame() {
        return cleanString(_targetFrame);
    }

    /**
     * Hyperlink address. Depending on the hyperlink type it can be URL, e-mail, path to a file, etc.
     *
     * @return  the address of this hyperlink
     */
    public String getAddress() {
        if ((_linkOpts & HLINK_URL) != 0 && FILE_MONIKER.equals(_moniker)) {
            return cleanString(_address != null ? _address : _shortFilename);
        } else if((_linkOpts & HLINK_PLACE) != 0) {
            return cleanString(_textMark);
        } else {
            return cleanString(_address);
        }
    }

    /**
     * Hyperlink address. Depending on the hyperlink type it can be URL, e-mail, path to a file, etc.
     *
     * @param address  the address of this hyperlink
     */
    public void setAddress(String address) {
        if ((_linkOpts & HLINK_URL) != 0 && FILE_MONIKER.equals(_moniker)) {
            _shortFilename = appendNullTerm(address);
        } else if((_linkOpts & HLINK_PLACE) != 0) {
            _textMark = appendNullTerm(address);
        } else {
            _address = appendNullTerm(address);
        }
    }

    public String getShortFilename() {
        return cleanString(_shortFilename);
    }

    public void setShortFilename(String shortFilename) {
        _shortFilename = appendNullTerm(shortFilename);
    }

    public String getTextMark() {
        return cleanString(_textMark);
    }
    public void setTextMark(String textMark) {
        _textMark = appendNullTerm(textMark);
    }


    /**
     * Link options. Must be a combination of HLINK_* constants.
     * For testing only
     *
     * @return Link options
     */
    int getLinkOptions(){
        return _linkOpts;
    }

    /**
     * @return Label options
     */
    public int getLabelOptions(){
        return 2; // always 2
    }

    /**
     * @return Options for a file link
     */
    public int getFileOptions(){
        return _fileOpts;
    }


    public HyperlinkRecord(RecordInputStream in) {
        _range = new CellRangeAddress(in);

        _guid = new ClassID(in);

        /*
         * streamVersion (4 bytes): An unsigned integer that specifies the version number
         * of the serialization implementation used to save this structure. This value MUST equal 2.
         */
        int streamVersion = in.readInt();
        if (streamVersion != 0x00000002) {
            throw new RecordFormatException("Stream Version must be 0x2 but found " + streamVersion);
        }
        _linkOpts = in.readInt();

        if ((_linkOpts & HLINK_LABEL) != 0){
            int label_len = in.readInt();
            _label = in.readUnicodeLEString(label_len);
        }

        if ((_linkOpts & HLINK_TARGET_FRAME) != 0){
            int len = in.readInt();
            _targetFrame = in.readUnicodeLEString(len);
        }

        if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) != 0) {
            _moniker = null;
            int nChars = in.readInt();
            _address = in.readUnicodeLEString(nChars);
        }

        if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) {
            _moniker = new ClassID(in);

            if(URL_MONIKER.equals(_moniker)){
                int length = in.readInt();
                /*
                 * The value of <code>length<code> be either the byte size of the url field
                 * (including the terminating NULL character) or the byte size of the url field plus 24.
                 * If the value of this field is set to the byte size of the url field,
                 * then the tail bytes fields are not present.
                 */
                int remaining = in.remaining();
                if (length == remaining) {
                    int nChars = length/2;
                    _address = in.readUnicodeLEString(nChars);
                } else {
                    int nChars = (length - TAIL_SIZE)/2;
                    _address = in.readUnicodeLEString(nChars);
                    /*
                     * TODO: make sense of the remaining bytes
                     * According to the spec they consist of:
                     * 1. 16-byte  GUID: This field MUST equal
                     *    {0xF4815879, 0x1D3B, 0x487F, 0xAF, 0x2C, 0x82, 0x5D, 0xC4, 0x85, 0x27, 0x63}
                     * 2. Serial version, this field MUST equal 0 if present.
                     * 3. URI Flags
                     */
                    _uninterpretedTail = readTail(URL_TAIL, in);
                }
            } else if (FILE_MONIKER.equals(_moniker)) {
                _fileOpts = in.readShort();

                int len = in.readInt();
                _shortFilename = StringUtil.readCompressedUnicode(in, len);
                _uninterpretedTail = readTail(FILE_TAIL, in);
                int size = in.readInt();
                if (size > 0) {
                    int charDataSize = in.readInt();

                    //From the spec: An optional unsigned integer that MUST be 3 if present
                    // but some files has 4
                    /*int usKeyValue = */ in.readUShort();

                    _address = StringUtil.readUnicodeLE(in, charDataSize/2);
                } else {
                    _address = null;
                }
            } else if (STD_MONIKER.equals(_moniker)) {
                _fileOpts = in.readShort();

                int len = in.readInt();

                byte[] path_bytes = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
                in.readFully(path_bytes);

                _address = new String(path_bytes, StringUtil.UTF8);
            }
        }

        if((_linkOpts & HLINK_PLACE) != 0) {

            int len = in.readInt();
            _textMark = in.readUnicodeLEString(len);
        }

        if (in.remaining() > 0) {
            LOG.atWarn().log("Hyperlink data remains: {} : {}", box(in.remaining()), toHex(in.readRemainder()));
        }
    }

    @Override
    public void serialize(LittleEndianOutput out) {
        _range.serialize(out);

        _guid.write(out);
        out.writeInt(0x00000002); // TODO const
        out.writeInt(_linkOpts);

        if ((_linkOpts & HLINK_LABEL) != 0){
            out.writeInt(_label.length());
            StringUtil.putUnicodeLE(_label, out);
        }
        if ((_linkOpts & HLINK_TARGET_FRAME) != 0){
            out.writeInt(_targetFrame.length());
            StringUtil.putUnicodeLE(_targetFrame, out);
        }

        if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) != 0) {
            out.writeInt(_address.length());
            StringUtil.putUnicodeLE(_address, out);
        }

        if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) {
            _moniker.write(out);
            if(URL_MONIKER.equals(_moniker)){
                if (_uninterpretedTail == null) {
                    out.writeInt(_address.length()*2);
                    StringUtil.putUnicodeLE(_address, out);
                } else {
                    out.writeInt(_address.length()*2 + TAIL_SIZE);
                    StringUtil.putUnicodeLE(_address, out);
                    writeTail(_uninterpretedTail, out);
                }
            } else if (FILE_MONIKER.equals(_moniker)){
                out.writeShort(_fileOpts);
                out.writeInt(_shortFilename.length());
                StringUtil.putCompressedUnicode(_shortFilename, out);
                writeTail(_uninterpretedTail, out);
                if (_address == null) {
                    out.writeInt(0);
                } else {
                    int addrLen = _address.length() * 2;
                    out.writeInt(addrLen + 6);
                    out.writeInt(addrLen);
                    out.writeShort(0x0003); // TODO const
                    StringUtil.putUnicodeLE(_address, out);
                }
            }
        }
        if((_linkOpts & HLINK_PLACE) != 0){
               out.writeInt(_textMark.length());
            StringUtil.putUnicodeLE(_textMark, out);
        }
    }

    @Override
    protected int getDataSize() {
        int size = 0;
        size += 2 + 2 + 2 + 2;  //rwFirst, rwLast, colFirst, colLast
        size += ClassID.LENGTH;
        size += 4;  //label_opts
        size += 4;  //link_opts
        if ((_linkOpts & HLINK_LABEL) != 0){
            size += 4;  //link length
            size += _label.length()*2;
        }
        if ((_linkOpts & HLINK_TARGET_FRAME) != 0){
            size += 4;  // int nChars
            size += _targetFrame.length()*2;
        }
        if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) != 0) {
            size += 4;  // int nChars
            size += _address.length()*2;
        }
        if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) {
            size += ClassID.LENGTH;
            if(URL_MONIKER.equals(_moniker)){
                size += 4;  //address length
                size += _address.length()*2;
                if (_uninterpretedTail != null) {
                    size += TAIL_SIZE;
                }
            } else if (FILE_MONIKER.equals(_moniker)){
                size += 2;  //file_opts
                size += 4;  //address length
                size += _shortFilename.length();
                size += TAIL_SIZE;
                size += 4;
                if (_address != null) {
                    size += 6;
                    size += _address.length() * 2;
                }

            }
        }
        if((_linkOpts & HLINK_PLACE) != 0){
            size += 4;  //address length
            size += _textMark.length()*2;
        }
        return size;
    }


    private static byte[] readTail(byte[] expectedTail, LittleEndianInput in) {
        byte[] result = new byte[TAIL_SIZE];
        in.readFully(result);
        return result;
    }

    private static void writeTail(byte[] tail, LittleEndianOutput out) {
        out.write(tail);
    }

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


    /**
     * Based on the link options, is this a url?
     *
     * @return true, if this is a url link
     */
    @SuppressWarnings("unused")
    public boolean isUrlLink() {
       return (_linkOpts & HLINK_URL) > 0
           && (_linkOpts & HLINK_ABS) > 0;
    }
    /**
     * Based on the link options, is this a file?
     *
     * @return true, if this is a file link
     */
    public boolean isFileLink() {
       return (_linkOpts & HLINK_URL) > 0
           && (_linkOpts & HLINK_ABS) == 0;
    }
    /**
     * Based on the link options, is this a document?
     *
     * @return true, if this is a docment link
     */
    public boolean isDocumentLink() {
       return (_linkOpts & HLINK_PLACE) > 0;
    }

    /**
     * Initialize a new url link
     */
    public void newUrlLink() {
        _range = new CellRangeAddress(0, 0, 0, 0);
        _guid = STD_MONIKER.getClassID();
        _linkOpts = HLINK_URL | HLINK_ABS | HLINK_LABEL;
        setLabel("");
        _moniker = URL_MONIKER.getClassID();
        setAddress("");
        _uninterpretedTail = URL_TAIL;
    }

    /**
     * Initialize a new file link
     */
    public void newFileLink() {
        _range = new CellRangeAddress(0, 0, 0, 0);
        _guid = STD_MONIKER.getClassID();
        _linkOpts = HLINK_URL | HLINK_LABEL;
        _fileOpts = 0;
        setLabel("");
        _moniker = FILE_MONIKER.getClassID();
        setAddress(null);
        setShortFilename("");
        _uninterpretedTail = FILE_TAIL;
    }

    /**
     * Initialize a new document link
     */
    public void newDocumentLink() {
        _range = new CellRangeAddress(0, 0, 0, 0);
        _guid = STD_MONIKER.getClassID();
        _linkOpts = HLINK_LABEL | HLINK_PLACE;
        setLabel("");
        _moniker = FILE_MONIKER.getClassID();
        setAddress("");
        setTextMark("");
    }

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

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

    @Override
    public Map<String, Supplier<?>> getGenericProperties() {
        return GenericRecordUtil.getGenericProperties(
            "range", () -> _range,
            "guid", this::getGuid,
            "linkOpts", () -> getBitsAsString(this::getLinkOptions,
                  new int[]{HLINK_URL,HLINK_ABS,HLINK_PLACE,HLINK_LABEL,HLINK_TARGET_FRAME,HLINK_UNC_PATH},
                  new String[]{"URL","ABS","PLACE","LABEL","TARGET_FRAME","UNC_PATH"}),
            "label", this::getLabel,
            "targetFrame", this::getTargetFrame,
            "moniker", this::getMoniker,
            "textMark", this::getTextMark,
            "address", this::getAddress
        );
    }
}
