% Copyright (C) 2023-2025 Kale Ewasiuk
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, including without limitation the rights
% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
% copies of the Software, and to permit persons to whom the Software is
% furnished to do so, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in
% all copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
% ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
% TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
% PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT
% SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
% ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
% ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
% OR OTHER DEALINGS IN THE SOFTWARE.


\ProvidesPackage{addtoluatexpath}[2025-01-11]

\RequirePackage{luacode}

\providecommand{\input@path}{} % initialize input@path if not defined yet

\begin{luacode*}
  addtoluatexpath = {}
  
  addtoluatexpath.paths = {"."} --  table containing paths added by this package

  function addtoluatexpath.find_file(f) -- find a path in list of addtoluatexpath.paths
    for i, k in pairs(addtoluatexpath.paths) do
      local fp = kpse.find_file(k ..'/'.. f)
      if (fp) then
        return fp
      end
    end -- if nothing returned, issue a package error
    texio.write_nl('addtoluatexpath searched for file: '..f)
    texio.write_nl('addtoluatexpath searched paths were: '..token.get_macro('input@path'))
    tex.sprint('\\PackageError{addtoluatexpath}{a file was not found, see log.}{}')
    tex.sprint('\\stop')
  end
  
  function addtoluatexpath.main(atlp_raw) -- add to path from raw string
    local penlight = require'penlight'
    
    local atlp_tbl = require'luakeys'().parse(atlp_raw, {naked_as_value=true}) -- paths as table

    local atlp_no_lua = atlp_tbl['nolua'] or false  -- check and set nolua=true
    local atlp_no_tex = atlp_tbl['notex'] or false  -- check and set notex=true
    local atlp_no_error = atlp_tbl['noerror'] or false  -- check and set noerror=true

    atlp_tbl = penlight.List(atlp_tbl) -- convert to pl.List for easy manipulation

    for __, p in ipairs(atlp_tbl) do
      if p:find('*') == nil then -- add paths without *, and continue the loop after
        if not atlp_no_lua then package.path = package.path .. ';'..p..'/?.lua;' end
        if not atlp_no_tex then  token.set_macro('input@path', token.get_macro('input@path')..'{'..p..'/}', 'global') end
        if (not atlp_no_error) and (not penlight.path.exists(p)) then
              tex.sprint('\\PackageError{addtoluatexpath}{directory "'..p..'" was not found}{}')
        end
        addtoluatexpath.paths[#addtoluatexpath.paths + 1] = p -- append the added path to global list
      else
        local p, c  = p:gsub('*','') -- if * added, include subdirectories
        local atlp_subdirs = penlight.List(penlight.dir.getdirectories(p))
        -- troubleshooting --texio.write_nl(penlight.pretty.write(atlp_subdirs))
        if c == 2 then
          atlp_subdirs = atlp_subdirs:map(function(s) return s ..'/**'  end) -- add ** to subdirs for recursive inclusion
        end
        atlp_tbl:append(p) -- make sure p (current path without *) is still added!
        atlp_tbl:extend(atlp_subdirs) -- extend path to include additional subdirs; the for loop is lengthened
      end
    end
  end
    
  
  function addtoluatexpath.prt_paths()
    texio.write_nl('Lua Paths >>> \n'..package.path:gsub(';','\n'))
    texio.write_nl('\nTeX Paths >>> \n'..token.get_macro('input@path'):gsub('}{','\n'))
  end
  
  ---- ---- ---- add paths passed as package options
  addtoluatexpath.main(token.get_macro('@raw@opt@addtoluatexpath.sty'))
  ---- ---- ----
  
\end{luacode*}

\NewDocumentCommand{\addtoluatexpath}{m}{\luadirect{addtoluatexpath.main(\luastring{#1})}}  % a command

\AtEndOfPackage{\let\@unprocessedoptions\relax}
