package org.bouncycastle.dvcs;

import java.math.BigInteger;
import java.util.Date;

import org.bouncycastle.asn1.dvcs.DVCSRequestInformation;
import org.bouncycastle.asn1.dvcs.DVCSTime;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.PolicyInformation;
import org.bouncycastle.tsp.TimeStampToken;
import org.bouncycastle.util.Arrays;

/**
 * Information piece of DVCS requests.
 * It is common for all types of DVCS requests.
 */
public class DVCSRequestInfo
{
    private DVCSRequestInformation data;

    /**
     * Constructs DVCRequestInfo from byte array (DER encoded DVCSRequestInformation).
     *
     * @param in a byte array holding the encoding of a DVCSRequestInformation structure.
     */
    public DVCSRequestInfo(byte[] in)
    {
        this(DVCSRequestInformation.getInstance(in));
    }

    /**
     * Constructs DVCRequestInfo from DVCSRequestInformation ASN.1 structure.
     *
     * @param data a DVCSRequestInformation to populate this object with.
     */
    public DVCSRequestInfo(DVCSRequestInformation data)
    {
        this.data = data;
    }

    /**
     * Converts to corresponding ASN.1 structure (DVCSRequestInformation).
     *
     * @return a DVCSRequestInformation object.
     */
    public DVCSRequestInformation toASN1Structure()
    {
        return data;
    }

    //
    // DVCRequestInfo selector interface
    //

    /**
     * Get DVCS version of request.
     *
     * @return the version number of the request.
     */
    public int getVersion()
    {
        return data.getVersion();
    }

    /**
     * Get requested service type.
     *
     * @return one of CPD, VSD, VPKC, CCPD (see constants).
     */
    public int getServiceType()
    {
        return data.getService().getValue().intValue();
    }

    /**
     * Get nonce if it is set.
     * Note: this field can be set (if not present) or extended (if present) by DVCS.
     *
     * @return nonce value, or null if it is not set.
     */
    public BigInteger getNonce()
    {
        return data.getNonce();
    }

    /**
     * Get request generation time if it is set.
     *
     * @return time of request, or null if it is not set.
     * @throws DVCSParsingException if a request time is present but cannot be extracted.
     */
    public Date getRequestTime()
        throws DVCSParsingException
    {
        DVCSTime time = data.getRequestTime();

        if (time == null)
        {
            return null;
        }

        try
        {
            if (time.getGenTime() != null)
            {
                return time.getGenTime().getDate();
            }
            else
            {
                TimeStampToken token = new TimeStampToken(time.getTimeStampToken());

                return token.getTimeStampInfo().getGenTime();
            }
        }
        catch (Exception e)
        {
            throw new DVCSParsingException("unable to extract time: " + e.getMessage(), e);
        }
    }

    /**
     * Get names of requesting entity, if set.
     *
     * @return the requesting entity, or null.
     */
    public GeneralNames getRequester()
    {
        return data.getRequester();
    }

    /**
     * Get policy, under which the validation is requested.
     *
     * @return policy identifier or null, if any policy is acceptable.
     */
    public PolicyInformation getRequestPolicy()
    {
        if (data.getRequestPolicy() != null)
        {
            return data.getRequestPolicy();
        }
        return null;
    }

    /**
     * Get names of DVCS servers.
     * Note: this field can be set by DVCS.
     *
     * @return the DVCS names object, or null if not set.
     */
    public GeneralNames getDVCSNames()
    {
        return data.getDVCS();
    }

    /**
     * Get data locations, where the copy of request Data can be obtained.
     * Note: the exact meaning of field is up to applications.
     * Note: this field can be set by DVCS.
     *
     * @return the DVCS dataLocations object, or null if not set.
     */
    public GeneralNames getDataLocations()
    {
        return data.getDataLocations();
    }

    /**
     * Compares two DVCRequestInfo structures: one from DVCRequest, and one from DVCResponse.
     * This function implements RFC 3029, 9.1 checks of reqInfo.
     *
     * @param requestInfo  - DVCRequestInfo of DVCRequest
     * @param responseInfo - DVCRequestInfo of DVCResponse
     * @return true if server's requestInfo matches client's requestInfo
     */
    public static boolean validate(DVCSRequestInfo requestInfo, DVCSRequestInfo responseInfo)
    {
        // RFC 3029, 9.1
        // The DVCS MAY modify the fields:
        // 'dvcs', 'requester', 'dataLocations', and 'nonce' of the ReqInfo structure.

        DVCSRequestInformation clientInfo = requestInfo.data;
        DVCSRequestInformation serverInfo = responseInfo.data;

        if (clientInfo.getVersion() != serverInfo.getVersion())
        {
            return false;
        }
        if (!clientEqualsServer(clientInfo.getService(), serverInfo.getService()))
        {
            return false;
        }
        if (!clientEqualsServer(clientInfo.getRequestTime(), serverInfo.getRequestTime()))
        {
            return false;
        }
        if (!clientEqualsServer(clientInfo.getRequestPolicy(), serverInfo.getRequestPolicy()))
        {
            return false;
        }
        if (!clientEqualsServer(clientInfo.getExtensions(), serverInfo.getExtensions()))
        {
            return false;
        }

        // RFC 3029, 9.1. The only modification allowed to a 'nonce'
        // is the inclusion of a new field if it was not present,
        // or to concatenate other data to the end (right) of an existing value.

        if (clientInfo.getNonce() != null)
        {
            if (serverInfo.getNonce() == null)
            {
                return false;
            }
            byte[] clientNonce = clientInfo.getNonce().toByteArray();
            byte[] serverNonce = serverInfo.getNonce().toByteArray();
            if (serverNonce.length < clientNonce.length)
            {
                return false;
            }
            if (!Arrays.areEqual(clientNonce, Arrays.copyOfRange(serverNonce, 0, clientNonce.length)))
            {
                return false;
            }
        }

        return true;
    }

    // null-protected compare of any two objects
    private static boolean clientEqualsServer(Object client, Object server)
    {
        return (client == null && server == null) || (client != null && client.equals(server));
    }
}

