package hirs.attestationca.persist.entity.userdefined.certificate.attributes;

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

import java.io.Serializable;
import java.math.BigInteger;

/**
 * A class to represent the TPM Security Assertions in an Endorsement Credential as
 * defined by the TCG spec for TPM 1.2.
 * <p>
 * https://www.trustedcomputinggroup.org/wp-content/uploads/IWG-Credential_Profiles_V1_R0.pdf
 * <p>
 * Future iterations of this code may want to reference
 * www.trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf
 * for specifications for TPM 2.0 (pg. 19).
 */
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString
@Embeddable
public class TPMSecurityAssertions implements Serializable {

    @Column
    private BigInteger tpmSecAssertsVersion; //default v1

    @Column
    private boolean fieldUpgradeable; //default false

    @Column
    private EkGenerationType ekGenType; //optional

    @Column
    private EkGenerationLocation ekGenerationLocation; //optionalv

    @Column
    private EkGenerationLocation ekCertificateGenerationLocation; //optional

    /**
     * Standard constructor that sets required fields. Use accessor methods
     * to set optional fields.
     *
     * @param version          the version of the security assertions
     * @param fieldUpgradeable whether or not the security assertions are
     *                         field upgradeable.
     */
    public TPMSecurityAssertions(final BigInteger version, final boolean fieldUpgradeable) {
        this.tpmSecAssertsVersion = version;
        this.fieldUpgradeable = fieldUpgradeable;
    }

    // Future work (may need to create other classes):
    //private CommonCriteriaMeasures commCritMeasures; //optional
    //private FIPSLevel fipsLevel; //optional
    //private boolean iso9000Certified; //default false
    //private IA5String iso9000Uri; //optional

    /**
     * A type to handle the different endorsement key generation types used in the TPM
     * Assertions field of an endorsement credential. Ordering of enum types is intentional
     * and their ordinal values correspond to enum values in the TCG spec.
     */

    public enum EkGenerationType {
        /**
         * Generated internally within the TPM and cannot be revoked. Enum value of 0.
         */
        INTERNAL,
        /**
         * Generated externally and then inserted under a controlled environment during
         * manufacturing. Cannot be revoked. Enum value of 1.
         */
        INJECTED,
        /**
         * Generated internally within the TPM and can be revoked. Enum value of 2.
         */
        INTERNAL_REVOCABLE,
        /**
         * Generated externally and then inserted under a controlled environment during
         * manufacturing. Can be revoked. Enum value of 3.
         */
        INJECTED_REVOCABLE
    }

    /**
     * A type to handle the different endorsement key generation locations used in
     * specifying the endorsement key generation location and the endorsement key
     * certificate generation location in the TPM Assertions field of an endorsement
     * credential. Ordering of enum types is intentional and their ordinal values
     * correspond to enum values in the TCG spec.
     */
    public enum EkGenerationLocation {
        /**
         * Generated by the TPM Manufacturer. Enum value of 0.
         */
        TPM_MANUFACTURER,
        /**
         * Generated by the Platform Manufacturer. Enum value of 1.
         */
        PLATFORM_MANUFACTURER,
        /**
         * Generated by the endorsement key certificate signer. Enum value of 2.
         */
        EK_CERT_SIGNER
    }
}
