"""ASN.1 definitions for condition objects.

.. code-block:: text

    Crypto-Conditions DEFINITIONS AUTOMATIC TAGS ::= BEGIN

        -- Conditions

        Condition ::= CHOICE {
          preimageSha256   [0] SimpleSha256Condition,
          prefixSha256     [1] CompoundSha256Condition,
          thresholdSha256  [2] CompoundSha256Condition,
          rsaSha256        [3] SimpleSha256Condition,
          ed25519Sha256    [4] SimpleSha256Condition
          zenroomSha256    [5] SimpleSha256Condition
        }

        SimpleSha256Condition ::= SEQUENCE {
          fingerprint          OCTET STRING (SIZE(32)),
          cost                 INTEGER (0..4294967295)
        }

        CompoundSha256Condition ::= SEQUENCE {
          fingerprint          OCTET STRING (SIZE(32)),
          cost                 INTEGER (0..4294967295),
          subtypes             ConditionTypes
        }

        ConditionTypes ::= BIT STRING {
          preImageSha256   (0),
          prefixSha256     (1),
          thresholdSha256  (2),
          rsaSha256        (3),
          ed25519Sha256    (4),
          zenroomSha256    (5)
        }

    END

"""
from pyasn1.type.namedval import NamedValues
from pyasn1.type.univ import BitString, Choice, Integer, OctetString, Sequence
from pyasn1.type.namedtype import NamedType, NamedTypes
from pyasn1.type.constraint import ValueRangeConstraint, ValueSizeConstraint
from pyasn1.type.tag import (
    Tag, tagClassContext, tagFormatConstructed, tagFormatSimple)

class ConditionTypes(BitString):
    namedValues = NamedValues(
        ('preImageSha256', 0),
        ('prefixSha256', 1),
        ('thresholdSha256', 2),
        ('rsaSha256', 3),
        ('ed25519Sha256', 4),
        ('zenroomSha256', 5),
    )

class CompoundSha256Condition(Sequence):
    componentType = NamedTypes(
        NamedType(
            'fingerprint',
            OctetString().subtype(
                subtypeSpec=ValueSizeConstraint(32, 32)).subtype(
                    implicitTag=Tag(tagClassContext, tagFormatSimple, 0))),
        NamedType(
            'cost',
            Integer().subtype(
                subtypeSpec=ValueRangeConstraint(0, 4294967295)).subtype(
                    implicitTag=Tag(tagClassContext, tagFormatSimple, 1))),
        NamedType(
            'subtypes',
            ConditionTypes().subtype(
                implicitTag=Tag(tagClassContext, tagFormatSimple, 2))),
    )

class SimpleSha256Condition(Sequence):
    componentType = NamedTypes(
        NamedType(
            'fingerprint',
            OctetString().subtype(
                subtypeSpec=ValueSizeConstraint(32, 32)).subtype(
                    implicitTag=Tag(tagClassContext, tagFormatSimple, 0))),
        NamedType(
            'cost',
            Integer().subtype(
                subtypeSpec=ValueRangeConstraint(0, 4294967295)).subtype(
                    implicitTag=Tag(tagClassContext, tagFormatSimple, 1))),
    )

class Condition(Choice):
    componentType = NamedTypes(
        NamedType(
            'preimageSha256',
            SimpleSha256Condition().subtype(
                implicitTag=Tag(tagClassContext, tagFormatConstructed, 0))),
        NamedType(
            'prefixSha256',
            CompoundSha256Condition().subtype(
                implicitTag=Tag(tagClassContext, tagFormatConstructed, 1))),
        NamedType(
            'thresholdSha256',
            CompoundSha256Condition().subtype(
                implicitTag=Tag(tagClassContext, tagFormatConstructed, 2))),
        NamedType(
            'rsaSha256',
            SimpleSha256Condition().subtype(
                implicitTag=Tag(tagClassContext, tagFormatConstructed, 3))),
        NamedType(
            'ed25519Sha256',
            SimpleSha256Condition().subtype(
                implicitTag=Tag(tagClassContext, tagFormatConstructed, 4))),
        NamedType(
            'zenroomSha256',
            SimpleSha256Condition().subtype(
                implicitTag=Tag(tagClassContext, tagFormatConstructed, 5))),
    )
