local _tl_compat; if (tonumber((_VERSION or ''):match('[%d.]*$')) or 0) < 5.3 then local p, m = pcall(require, 'compat53.module'); if p then _tl_compat = m end end; local io = _tl_compat and _tl_compat.io or io; local ipairs = _tl_compat and _tl_compat.ipairs or ipairs; local string = _tl_compat and _tl_compat.string or string


local doc = {}


local util = require("luarocks.util")
local queries = require("luarocks.queries")
local search = require("luarocks.search")
local path = require("luarocks.path")
local dir = require("luarocks.dir")
local fetch = require("luarocks.fetch")
local fs = require("luarocks.fs")
local download = require("luarocks.download")






function doc.add_to_parser(parser)
   local cmd = parser:command("doc", "Show documentation for an installed rock.\n\n" ..
   "Without any flags, tries to load the documentation using a series of heuristics.\n" ..
   "With flags, return only the desired information.", util.see_also([[
   For more information about a rock, see the 'show' command.
]])):
   summary("Show documentation for an installed rock.")

   cmd:argument("rock", "Name of the rock."):
   action(util.namespaced_name_action)
   cmd:argument("version", "Version of the rock."):
   args("?")

   cmd:flag("--home", "Open the home page of project.")
   cmd:flag("--list", "List documentation files only.")
   cmd:flag("--porcelain", "Produce machine-friendly output.")
end

local function show_homepage(homepage, name, namespace, version)
   if not homepage then
      return nil, "No 'homepage' field in rockspec for " .. util.format_rock_name(name, namespace, version)
   end
   util.printout("Opening " .. homepage .. " ...")
   fs.browser(homepage)
   return true
end

local function try_to_open_homepage(name, namespace, version)
   local temp_dir, err
   temp_dir, err = fs.make_temp_dir("doc-" .. name .. "-" .. (version or ""))
   if not temp_dir then
      return nil, "Failed creating temporary directory: " .. err
   end

   util.schedule_function(fs.delete, temp_dir)

   local ok
   ok, err = fs.change_dir(temp_dir)
   if not ok then return nil, err end

   local filename
   filename, err = download.download_file("rockspec", name, namespace, version)
   if not filename then return nil, err end

   local rockspec
   rockspec, err = fetch.load_local_rockspec(filename)
   if not rockspec then return nil, err end

   fs.pop_dir()
   local descript = rockspec.description or {}
   return show_homepage(descript.homepage, name, namespace, version)
end



function doc.command(args)
   local query = queries.new(args.rock, args.namespace, args.version)
   local iname, iversion, repo = search.pick_installed_rock(query, args.tree)
   if not iname then
      local rock = util.format_rock_name(args.rock, args.namespace, args.version)
      util.printout(rock .. " is not installed. Looking for it in the rocks servers...")
      return try_to_open_homepage(args.rock, args.namespace, args.version)
   end
   local name, version = iname, iversion

   local rockspec, err = fetch.load_local_rockspec(path.rockspec_file(name, version, repo))
   if not rockspec then return nil, err end
   local descript = rockspec.description or {}

   if args.home then
      return show_homepage(descript.homepage, name, args.namespace, version)
   end

   local directory = path.install_dir(name, version, repo)

   local docdir
   local directories = { "doc", "docs" }
   for _, d in ipairs(directories) do
      local dirname = dir.path(directory, d)
      if fs.is_dir(dirname) then
         docdir = dirname
         break
      end
   end
   if not docdir then
      if descript.homepage and not args.list then
         util.printout("Local documentation directory not found -- opening " .. descript.homepage .. " ...")
         fs.browser(descript.homepage)
         return true
      end
      return nil, "Documentation directory not found for " .. name .. " " .. version
   end

   docdir = dir.normalize(docdir)
   local files = fs.find(docdir)
   local htmlpatt = "%.html?$"
   local extensions = { htmlpatt, "%.md$", "%.txt$", "%.textile$", "" }
   local basenames = { "index", "readme", "manual" }

   local porcelain = args.porcelain
   if #files > 0 then
      util.title("Documentation files for " .. name .. " " .. version, porcelain)
      if porcelain then
         for _, file in ipairs(files) do
            util.printout(docdir .. "/" .. file)
         end
      else
         util.printout(docdir .. "/")
         for _, file in ipairs(files) do
            util.printout("\t" .. file)
         end
      end
   end

   if args.list then
      return true
   end

   for _, extension in ipairs(extensions) do
      for _, basename in ipairs(basenames) do
         local filename = basename .. extension
         local found
         for _, file in ipairs(files) do
            if file:lower():match(filename) and ((not found) or #file < #found) then
               found = file
            end
         end
         if found then
            local pathname = dir.path(docdir, found)
            util.printout()
            util.printout("Opening " .. pathname .. " ...")
            util.printout()
            local ok = fs.browser(pathname)
            if not ok and not pathname:match(htmlpatt) then
               local fd = io.open(pathname, "r")
               util.printout(fd:read("*a"))
               fd:close()
            end
            return true
         end
      end
   end

   return true
end


return doc
