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

import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;

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

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.poi.util.GenericRecordUtil;

/**
 * Definition of a special kind of property of some text, or its
 *  paragraph. For these properties, a flag in the "contains" header
 *  field tells you the data property family will exist. The value
 *  of the property is itself a mask, encoding several different
 *  (but related) properties
 */
public abstract class BitMaskTextProp extends TextProp {
    protected static final Logger LOG = LogManager.getLogger(BitMaskTextProp.class);

	private String[] subPropNames;
	private int[] subPropMasks;
	private boolean[] subPropMatches;

	/** Fetch the list of the names of the sub properties */
	public String[] getSubPropNames() { return subPropNames; }
	/** Fetch the list of if the sub properties match or not */
	public boolean[] getSubPropMatches() { return subPropMatches; }


	protected BitMaskTextProp(BitMaskTextProp other) {
		super(other);
		subPropNames = (other.subPropNames == null) ? null : other.subPropNames.clone();
		subPropMasks = (other.subPropMasks == null) ? null : other.subPropMasks.clone();

		// The old clone implementation didn't carry over matches, but keep everything else as it was
		// this is failing unit tests
		// subPropMatches = (other.subPropMatches == null) ? null : new boolean[other.subPropMatches.length];
		subPropMatches = (other.subPropMatches == null) ? null : other.subPropMatches.clone();
	}


	protected BitMaskTextProp(int sizeOfDataBlock, int maskInHeader, String overallName, String... subPropNames) {
		super(sizeOfDataBlock,maskInHeader,overallName);
		this.subPropNames = subPropNames;
		subPropMasks = new int[subPropNames.length];
		subPropMatches = new boolean[subPropNames.length];

		int LSB = Integer.lowestOneBit(maskInHeader);

		// Initialise the masks list
		for(int i=0; i<subPropMasks.length; i++) {
			subPropMasks[i] = (LSB << i);
		}
	}

	/**
	 * Calculate mask from the subPropMatches.
	 */
	@Override
	public int getWriteMask() {
	    /*
	     * The dataValue can't be taken as a mask, as sometimes certain properties
	     * are explicitly set to false, i.e. the mask says the property is defined
	     * but in the actually nibble the property is set to false
	     */
	    int mask = 0, i = 0;
	    for (int subMask : subPropMasks) {
	        if (subPropMatches[i++]) mask |= subMask;
	    }
		return mask;
	}

	/**
	 * Sets the write mask, i.e. which defines the text properties to be considered
	 *
	 * @param writeMask the mask, bit values outside the property mask range will be ignored
	 */
	public void setWriteMask(int writeMask) {
        int i = 0;
        for (int subMask : subPropMasks) {
            subPropMatches[i++] = ((writeMask & subMask) != 0);
        }
	}

	/**
	 * Return the text property value.
	 * Clears all bits of the value, which are marked as unset.
	 *
	 * @return the text property value.
	 */
	@Override
	public int getValue() {
	    return maskValue(super.getValue());
	}

	private int maskValue(int pVal) {
        int val = pVal, i = 0;
        for (int mask : subPropMasks) {
            if (!subPropMatches[i++]) {
                val &= ~mask;
            }
        }
        return val;
	}

	/**
	 * Set the value of the text property, and recompute the sub
	 * properties based on it, i.e. all unset subvalues will be cleared.
	 * Use {@link #setSubValue(boolean, int)} to explicitly set subvalues to {@code false}.
	 */
	@Override
	public void setValue(int val) {
		super.setValue(val);

		// Figure out the values of the sub properties
		int i = 0;
		for(int mask : subPropMasks) {
		    subPropMatches[i++] = ((val & mask) != 0);
		}
	}

	/**
	 * Convenience method to set a value with mask, without splitting it into the subvalues
	 *
	 * @param val
	 * @param writeMask
	 */
	public void setValueWithMask(int val, int writeMask) {
	    setWriteMask(writeMask);
	    super.setValue(maskValue(val));
	    if (val != super.getValue()) {
			LOG.atWarn().log("Style properties of '{}' don't match mask - output will be sanitized", getName());
			LOG.atDebug().log(() -> {
	            StringBuilder sb = new StringBuilder("The following style attributes of the '")
						.append(getName()).append("' property will be ignored:\n");
	            int i=0;
	            for (int mask : subPropMasks) {
	                if (!subPropMatches[i] && (val & mask) != 0) {
	                    sb.append(subPropNames[i]).append(",");
	                }
	                i++;
	            }
	            return new SimpleMessage(sb);
			});
	    }
	}

	/**
	 * Fetch the true/false status of the subproperty with the given index
	 */
	public boolean getSubValue(int idx) {
		return subPropMatches[idx] && ((super.getValue() & subPropMasks[idx]) != 0);
	}

	/**
	 * Set the true/false status of the subproperty with the given index
	 */
	public void setSubValue(boolean value, int idx) {
        subPropMatches[idx] = true;
        int newVal = super.getValue();
        if (value) {
            newVal |= subPropMasks[idx];
        } else {
            newVal &= ~subPropMasks[idx];
        }
        super.setValue(newVal);
	}

	/**
	 * @return an identical copy of this, i.e. also the subPropMatches are copied
	 */
	public BitMaskTextProp cloneAll(){
		BitMaskTextProp bmtp = copy();
		if (subPropMatches != null) {
			System.arraycopy(subPropMatches, 0, bmtp.subPropMatches, 0, subPropMatches.length);
		}
		return bmtp;
    }

	@Override
	public Map<String, Supplier<?>> getGenericProperties() {
		return GenericRecordUtil.getGenericProperties(
			"base", super::getGenericProperties,
			"flags", getBitsAsString(this::getValue, subPropMasks, subPropNames)
		);
	}

	@Override
	public abstract BitMaskTextProp copy();
}