/* ====================================================================
   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.hwpf.model;

import java.util.Arrays;
import java.util.Objects;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hwpf.model.types.StdfBaseAbstractType;
import org.apache.poi.hwpf.usermodel.CharacterProperties;
import org.apache.poi.hwpf.usermodel.ParagraphProperties;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.StringUtil;

import static org.apache.logging.log4j.util.Unbox.box;

@Internal
public final class StyleDescription {

    private static final Logger LOG = LogManager.getLogger(StyleDescription.class);
    //arbitrarily selected; may need to increase
    private static final int MAX_RECORD_LENGTH = 100_000;

    private static final int PARAGRAPH_STYLE = 1;
    private static final int CHARACTER_STYLE = 2;
    // private static final int TABLE_STYLE = 3;
    // private static final int NUMBERING_STYLE = 4;

    private int _baseLength;
    private StdfBase _stdfBase;
    private StdfPost2000 _stdfPost2000;

    UPX[] _upxs;
    String _name;
    @Deprecated
    ParagraphProperties _pap;
    @Deprecated
    CharacterProperties _chp;

    public StyleDescription() {
//      _pap = new ParagraphProperties();
//      _chp = new CharacterProperties();
    }

    public StyleDescription(byte[] std, int baseLength, int offset, boolean word9) {
        _baseLength = baseLength;
        int nameStart = offset + baseLength;

        boolean readStdfPost2000 = false;
        if (baseLength == 0x0012) {
            readStdfPost2000 = true;
        } else if (baseLength == 0x000A) {
            readStdfPost2000 = false;
        } else {
            LOG.atWarn().log("Style definition has non-standard size of {}", box(baseLength));
        }

        _stdfBase = new StdfBase(std, offset);
        offset += StdfBaseAbstractType.getSize();

        if (readStdfPost2000) {
            _stdfPost2000 = new StdfPost2000(std, offset);
            // offset += StdfPost2000.getSize();
        }

        //first byte(s) of variable length section of std is the length of the
        //style name and aliases string
        int nameLength = 0;
        int multiplier = 1;
        if (word9) {
            nameLength = LittleEndian.getShort(std, nameStart);
            multiplier = 2;
            nameStart += LittleEndianConsts.SHORT_SIZE;
        } else {
            nameLength = std[nameStart];
        }

        _name = StringUtil.getFromUnicodeLE(std, nameStart, (nameLength * multiplier) / 2);

        //length then null terminator.

        // the spec only refers to two possible upxs but it mentions
        // that more may be added in the future
        int varOffset = ((nameLength + 1) * multiplier) + nameStart;
        int countOfUPX = _stdfBase.getCupx();
        _upxs = new UPX[countOfUPX];
        for (int x = 0; x < countOfUPX; x++) {
            int upxSize = LittleEndian.getShort(std, varOffset);
            varOffset += LittleEndianConsts.SHORT_SIZE;

            byte[] upx = IOUtils.safelyClone(std, varOffset, upxSize, Short.MAX_VALUE);
            _upxs[x] = new UPX(upx);
            varOffset += upxSize;


            // the upx will always start on a word boundary.
            if ((upxSize & 1) == 1) {
                ++varOffset;
            }

        }


    }

    public int getBaseStyle() {
        return _stdfBase.getIstdBase();
    }

    public byte[] getCHPX() {
        switch (_stdfBase.getStk()) {
            case PARAGRAPH_STYLE:
                if (_upxs.length > 1) {
                    return _upxs[1].getUPX();
                }
                return null;
            case CHARACTER_STYLE:
                return _upxs[0].getUPX();
            default:
                return null;
        }

    }

    public byte[] getPAPX() {
        return _stdfBase.getStk() == PARAGRAPH_STYLE ? _upxs[0].getUPX() : null;
    }

    @Deprecated
    public ParagraphProperties getPAP() {
        return _pap;
    }

    @Deprecated
    public CharacterProperties getCHP() {
        return _chp;
    }

    @Deprecated
    void setPAP(ParagraphProperties pap) {
        _pap = pap;
    }

    @Deprecated
    void setCHP(CharacterProperties chp) {
        _chp = chp;
    }

    public String getName() {
        return _name;
    }

    public byte[] toByteArray() {
        // size equals _baseLength bytes for known variables plus 2 bytes for name
        // length plus name length * 2 plus 2 bytes for null plus upx's preceded by
        // length
        int size = _baseLength + 2 + ((_name.length() + 1) * 2);

        // determine the size needed for the upxs. They always fall on word
        // boundaries.
        size += _upxs[0].size() + 2;
        for (int x = 1; x < _upxs.length; x++) {
            size += _upxs[x - 1].size() % 2;
            size += _upxs[x].size() + 2;
        }


        byte[] buf = new byte[size];
        _stdfBase.serialize(buf, 0);

        int offset = _baseLength;

        char[] letters = _name.toCharArray();
        LittleEndian.putShort(buf, _baseLength, (short) letters.length);
        offset += LittleEndianConsts.SHORT_SIZE;
        for (char letter : letters) {
            LittleEndian.putShort(buf, offset, (short) letter);
            offset += LittleEndianConsts.SHORT_SIZE;
        }
        // get past the null delimiter for the name.
        offset += LittleEndianConsts.SHORT_SIZE;

        for (UPX upx : _upxs) {
            short upxSize = (short) upx.size();
            LittleEndian.putShort(buf, offset, upxSize);
            offset += LittleEndianConsts.SHORT_SIZE;
            System.arraycopy(upx.getUPX(), 0, buf, offset, upxSize);
            offset += upxSize + (upxSize % 2);
        }

        return buf;
    }

    @Override
    public int hashCode() {
        return Arrays.deepHashCode(new Object[]{_name,_stdfBase,_upxs});
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!(obj instanceof StyleDescription))
            return false;
        StyleDescription other = (StyleDescription) obj;
        if (!Objects.equals(_name, other._name)) {
            return false;
        }
        if (!Objects.equals(_stdfBase, other._stdfBase)) {
            return false;
        }
        return Arrays.equals(_upxs, other._upxs);
    }

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        result.append("[STD]: '");
        result.append(_name);
        result.append("'");
        result.append(("\nStdfBase:\t" + _stdfBase).replaceAll("\n",
                "\n    "));
        result.append(("\nStdfPost2000:\t" + _stdfPost2000).replaceAll(
                "\n", "\n    "));
        for (UPX upx : _upxs) {
            result.append(("\nUPX:\t" + upx).replaceAll("\n", "\n    "));
        }
        return result.toString();
    }
}
