-- gitano.plugins
--
-- Plugin loading support for Gitano
--
-- Copyright 2014-2017 Daniel Silverstone <daniel.silverstone@codethink.co.uk>
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions
-- are met:
-- 1. Redistributions of source code must retain the above copyright
--    notice, this list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright
--    notice, this list of conditions and the following disclaimer in the
--    documentation and/or other materials provided with the distribution.
-- 3. Neither the name of the author nor the names of their contributors
--    may be used to endorse or promote products derived from this software
--    without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-- SUCH DAMAGE.
--

local util = require "gitano.util"
local log = require "gitano.log"
local i18n = require "gitano.i18n"
local pat = require "gitano.patterns"

local luxio = require "luxio"
local sio = require "luxio.simple"

local gfind = string.gfind

local function find_plugins(path)
   local ret = {}
   for _, entry in ipairs(path) do
      local dirp, err = sio.opendir(entry)
      if not dirp then
         log.warning(i18n.expand("WARN_UNABLE_SCAN_PLUGINDIR",
                                 {dir=entry, reason=err}))
      else
         for filename, fileinfo in dirp:iterate() do
            local plugin_name = filename:match(pat.PLUGIN_NAME)
            if plugin_name then
               if not ret[plugin_name] then
                  ret[plugin_name] = entry
                  ret[#ret + 1] = plugin_name
               end
            end
         end
      end
   end
   table.sort(ret)
   return ret
end

local function load_plugins(path)
   local to_load = find_plugins(path)
   for _, plugin_name in ipairs(to_load) do
      local filepath = util.path_join(to_load[plugin_name],
                                      plugin_name .. ".lua")
      local chunk, err = loadfile(filepath)
      if not chunk then
         log.warning(i18n.expand("WARN_UNABLE_LOAD_PLUGIN",
                                 { plugin=plugin_name,
                                   file=to_load[plugin_name],
                                   reason=err }))
      else
         local ok, err = pcall(chunk)
         if not ok then
            log.warning(i18n.expand("WARN_UNABLE_RUN_PLUGIN",
                                    { plugin=plugin_name,
                                      file=to_load[plugin_name],
                                      reason=err }))
         end
      end
      i18n.add_plugin_path(util.path_join(to_load[plugin_name],
                                          plugin_name))
   end
end

return {
   load_plugins = load_plugins,
}
