#include "timing.inc"
module test_alphas
  use types
  use unit_tests
  use qcd_coupling
  implicit none

contains

  subroutine unit_tests_alphas()
    use new_as
    implicit none
    integer  :: nloop
    !-- reference results generated by unit-tests/gen-alphas-ref.py
    real(dp), parameter :: mc=1.670000_dp, mb=4.780000_dp, mt=172.570000_dp, mz=91.188000_dp
    real(dp), parameter :: alphas_mz=0.118000_dp
    real(dp), parameter :: Qvals(*) = [1.000000_dp, 3.000000_dp, 9.000000_dp, 10000.000000_dp]
    real(dp), parameter :: Qmin = Qvals(1), Qmax = Qvals(size(Qvals))
    integer , parameter :: nQ_fine = 200
    integer  :: iQ
    real(dp), parameter :: Qvals_fine(0:nQ_fine) = [(Qmin*(Qmax/Qmin)**(real(iQ,dp)/(nQ_fine)), iQ=0,nQ_fine)]
    !-- reference results for alphas_vfn
    real(dp), parameter :: ref_4loop_vfn(*) = [4.830605117006e-01_dp, 2.536789691195e-01_dp, 1.827498038423e-01_dp, 7.181752397345e-02_dp]
    !-- end of reference results    

    type(running_coupling) :: alphas_vfn, alphas_nf4
    real(dp) :: default_dt, Q, abs_tol = 1e-9_dp

    if (.not. do_test("unit_tests_alphas")) return


    default_dt = DefaultCouplingDt()
    !call SetDefaultCouplingDt(0.1_dp*default_dt)

    call InitRunningCoupling(alphas_vfn, alphas_mz, Q=mz, quark_masses=(/ mc, mb, mt /), nloop=4)
    call InitRunningCoupling(alphas_nf4, alphas_vfn%Value(2.0_dp), Q=2.0_dp, fixnf=4, nloop=4)

    do iQ = 1, size(Qvals)
      Q = Qvals(iQ)
      call check_approx_eq_0d("alphas_vfn at Q="//trim(to_string(Q)), alphas_vfn%Value(Q), ref_4loop_vfn(iQ), abs_tol)
    end do

    ! make sure that extraction outside of the range with fixnf works too
    call check_approx_eq("alphas_nf4_1GeV", alphas_nf4%Value(1.0_dp), alphas_vfn%Value(1.0_dp, fixnf=4), abs_tol)
    call check_approx_eq("alphas_nf4_9GeV", alphas_nf4%Value(9.0_dp), alphas_vfn%Value(9.0_dp, fixnf=4), abs_tol)

    ! test that evolution and interpolation variants are giving the same result
    ! to within the tolerance
    do iQ = 0, ubound(Qvals_fine,1)
      Q = Qvals_fine(iQ)
      call check_approx_eq("alphas: interp v. evol at Q="//trim(to_string(Q)), &
                           alphas_vfn%Value(Q), &
                           na_Value_full(alphas_vfn%nah,Q), abs_tol)
    end do

    TIME_START("alphas_vfn",10**7)
    real(dp) :: sum_alphas = 0.0_dp
    TIME_LOOP
      sum_alphas = sum_alphas + alphas_vfn%Value(Qvals(mod(irep,size(Qvals))+1))
      ! for testing impact of using a single Q value: saves about 1ns
      ! on M2Pro-gfortran15.1-O3
      !sum_alphas = sum_alphas + alphas_vfn%Value(6.0_dp)
    TIME_END(sum_alphas)

    TIME_START("alphas_vfn_full",10**7)
    real(dp) :: sum_alphas = 0.0_dp
    TIME_LOOP
      sum_alphas = sum_alphas + na_Value_full(alphas_vfn%nah,Qvals(mod(irep,size(Qvals))+1) ) !alphas_vfn%Value(Qvals(mod(irep,size(Qvals))+1))
    TIME_END(sum_alphas)


  end subroutine unit_tests_alphas

end module test_alphas