import math


def stakePoolTicketFee(stakeDiff, relayFee, height, poolFee, subsidyCache, netParams):
    """
    stakePoolTicketFee determines the stake pool ticket fee for a given ticket
    from the passed percentage. Pool fee as a percentage is truncated from 0.01%
    to 100.00%. This all must be done with integers.

    Args:
        stakeDiff (int): The ticket price.
        relayFee (int): Transaction fees.
        height (int): Current block height.
        poolFee (int): The pools fee, as percent.
        subsidyCache (calc.SubsidyCache): A subsidy cache.
        netParams (module): The network parameters.

    Returns:
        int: The stake pool ticket fee.

    """
    # Shift the decimal two places, e.g. 1.00%
    # to 100. This assumes that the proportion
    # is already multiplied by 100 to give a
    # percentage, thus making the entirety
    # be a multiplication by 10000.
    poolFeeAbs = math.floor(poolFee * 100.0)
    poolFeeInt = int(poolFeeAbs)

    # Subsidy is fetched from the blockchain package, then
    # pushed forward a number of adjustment periods for
    # compensation in gradual subsidy decay. Recall that
    # the average time to claiming 50% of the tickets as
    # votes is the approximately the same as the ticket
    # pool size (netParams.TicketPoolSize), so take the
    # ceiling of the ticket pool size divided by the
    # reduction interval.
    adjs = int(math.ceil(netParams.TicketPoolSize / netParams.SubsidyReductionInterval))
    subsidy = subsidyCache.calcStakeVoteSubsidy(height)
    for i in range(adjs):
        subsidy *= 100
        subsidy = subsidy // 101

    # The numerator is (p*10000*s*(v+z)) << 64.
    shift = 64
    s = subsidy
    v = int(stakeDiff)
    z = int(relayFee)
    num = poolFeeInt
    num *= s
    vPlusZ = v + z
    num *= vPlusZ
    num = num << shift

    # The denominator is 10000*(s+v).
    # The extra 10000 above cancels out.
    den = s
    den += v
    den *= 10000

    # Divide and shift back.
    num = num // den
    num = num >> shift

    return num