!> @file config_dim.f90
!> @brief Dimension pre-pass: read only the &control group from a namelist file.
!!
!! The unified namelist surface declares the problem dimension once, at the top,
!! in a `&control` group: `dim = 1 | 2 | 3`. This module reads ONLY that group so
!! the `euler` launcher can route to the right solver before the dimension-specific
!! config reader runs. A file with no `&control` group defaults to `dim = 1`, so
!! every pre-existing 1D namelist keeps working unchanged.
module config_dim
  use, intrinsic :: iso_fortran_env, only: iostat_end
  implicit none
  private
  public :: read_dim

contains

  !> Read the problem dimension from the &control group of `filename`.
  !!
  !! @param[in]  filename  path to the namelist file
  !! @param[out] dim       1, 2, or 3 (defaults to 1 when &control is absent)
  !! @param[out] ok        .true. on success; .false. on open/parse/range error
  !! @param[out] message   human-readable error when ok is .false.
  subroutine read_dim(filename, dim, ok, message)
    character(len=*), intent(in) :: filename
    integer, intent(out) :: dim
    logical, intent(out) :: ok
    character(len=*), intent(out) :: message

    integer :: u, ios, cstat
    namelist /control/ dim

    ok = .false.
    message = ''
    dim = 1   ! default when &control is absent

    open (newunit=u, file=filename, status='old', action='read', iostat=ios)
    if (ios /= 0) then
      message = 'config_dim: cannot open "'//trim(filename)//'"'
      return
    end if

    rewind (u)   ! defensive: ensure position at start before the single group read
    read (u, nml=control, iostat=ios)
    close (u, iostat=cstat)
    if (ios /= 0 .and. ios /= iostat_end) then
      message = 'config_dim: parse error in &control namelist'
      return
    end if

    if (dim < 1 .or. dim > 3) then
      write (message, '(a,i0,a)') 'config_dim: dim must be 1, 2, or 3 (got ', dim, ')'
      return
    end if

    ok = .true.
  end subroutine read_dim

end module config_dim
