package hirs;

import static org.apache.logging.log4j.LogManager.getLogger;
import hirs.data.persist.IMAReport;
import hirs.data.persist.Report;

import javax.xml.bind.annotation.XmlElement;

import org.apache.logging.log4j.Logger;

/**
 * <code>IMAReportRequest</code> is an immutable class and extends
 * <code>ReportRequest</code> to specify parameters which define
 * the composition of the IMA report to be generated by the client.
 * For example, <code>IMAReportRequest</code> specifies whether a full IMA
 * report should be generated and submitted for appraisal or whether a delta
 * report (containing new entries since last full report) should be generated
 * and submitted.  If a delta report is being requested, then an index must be
 * provided which is used to inform the client which subset of measurements
 * to include in the report.
 */
public final class IMAReportRequest implements ReportRequest {

    private static final Logger LOGGER = getLogger(IMAReportRequest.class);

    @XmlElement
    private final String bootcycleId;

    @XmlElement
    private final int index;

    /**
     * Default constructor required to enable marshalling and unmarshalling
     * to/from xml.
     */
    public IMAReportRequest() {
        this(null, 0);
    }

    /**
     * Creates a new <code>IMAReportRequest</code>. The boot-cycle ID and index
     * are set. The boot-cycle ID may be null to indicate that it is unknown by
     * the appraiser and a full report should be sent. The index is the index of
     * the new IMA record to send. An index of zero indicates a full report
     * should be sent.
     * <p>
     * If the boot-cycle is null then the index must be zero. Otherwise an
     * <code>IllegalArgumentException</code> is thrown.
     *
     * @param bootcycleId
     *            boot-cycle ID
     * @param i
     *            value to use as IMA index
     */
    public IMAReportRequest(final String bootcycleId, final int i) {
        LOGGER.debug("Entering constructor");
        if (i >= 0) {
            index = i;
        } else {
            String msg = "Cannot init IMAReportRequest with index less than 0";
            LOGGER.error(msg);
            throw new IllegalArgumentException(msg);
        }
        if (bootcycleId == null && i != 0) {
            String msg = "null boot-cycle ID must have index of 0";
            LOGGER.error(msg);
            throw new IllegalArgumentException(msg);
        }
        this.bootcycleId = bootcycleId;
        LOGGER.debug("Exiting constructor");
    }

    @Override
    public Class<? extends Report> getReportType() {
        return IMAReport.class;
    }

    /**
     * Returns the boot-cycle ID. This is the last boot-cycle ID that was saved
     * by the appraiser. If this is null or different than the boot-cycle ID for
     * the collector then a full report shall be sent.
     *
     * @return boot-cycle ID
     */
    public String getBootcycleId() {
        return bootcycleId;
    }

    /**
     * Method returns the IMA index.
     * @return index used to specify start location of measurement entries to
     *         include in IMA report
     */
    public int getIMAIndex() {
        return index;
    }

    @Override
    public String toString() {
        return String.format("(%s, %d)", bootcycleId, index);
    }
}
