# distutils: libraries = flint
"""Sage/FLINT bridge for certified Hardy Z jets and numbered zeta zeros."""
from sage.libs.flint.acb_dirichlet cimport acb_dirichlet_zeta_zero, acb_dirichlet_zeta_zeros, acb_dirichlet_hardy_z, acb_dirichlet_zeta_nzeros
from sage.libs.flint.acb cimport _acb_vec_init, _acb_vec_clear, acb_set
from sage.libs.flint.fmpz cimport fmpz_t, fmpz_init, fmpz_set_si, fmpz_clear
from sage.libs.flint.types cimport acb_ptr
from sage.rings.complex_arb cimport ComplexBall
from sage.rings.real_arb cimport RealBall
from sage.rings.complex_arb import ComplexBallField
from sage.rings.real_arb import RealBallField

def zero(long n, long prec):
    if n < 1: raise ValueError('n must be positive')
    cdef fmpz_t index
    cdef ComplexBall result = ComplexBallField(prec)(0)
    fmpz_init(index)
    try:
        fmpz_set_si(index, n)
        acb_dirichlet_zeta_zero(result.value, index, prec)
        return result
    finally:
        fmpz_clear(index)

def jet(t, long length, long prec):
    if length < 1: raise ValueError('length must be positive')
    field = ComplexBallField(prec)
    cdef ComplexBall argument = field(t)
    cdef ComplexBall coefficient
    cdef acb_ptr values = _acb_vec_init(length)
    cdef long j
    try:
        acb_dirichlet_hardy_z(values, argument.value, NULL, NULL, length, prec)
        result = []
        for j in range(length):
            coefficient = field(0)
            acb_set(coefficient.value, values+j)
            result.append(coefficient)
        return result
    finally:
        _acb_vec_clear(values,length)

def count(t, long prec):
    field = RealBallField(prec)
    cdef RealBall argument = field(t)
    cdef RealBall result = field(0)
    acb_dirichlet_zeta_nzeros(result.value, argument.value, prec)
    return result

def zero_prefix(long length, long prec):
    """Certified nontrivial zeros 1..length, for the finite indexing proof."""
    if length < 1: raise ValueError('length must be positive')
    cdef fmpz_t first
    cdef acb_ptr values = _acb_vec_init(length)
    cdef ComplexBall value
    cdef long j
    field = ComplexBallField(prec)
    fmpz_init(first)
    try:
        fmpz_set_si(first,1)
        acb_dirichlet_zeta_zeros(values, first, length, prec)
        result=[]
        for j in range(length):
            value=field(0)
            acb_set(value.value, values+j)
            result.append(value)
        return result
    finally:
        fmpz_clear(first)
        _acb_vec_clear(values,length)


cdef extern from "flint/flint.h":
    const char *FLINT_VERSION

def flint_version():
    return (<bytes>FLINT_VERSION).decode('ascii')
