-- gitano.repocommand
--
-- Gitano repository related commands such as gc, count-objects and fsck
--
-- Copyright 2012-2017 Daniel Silverstone <dsilvers@digital-scurf.org>
-- 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 log = require 'gitano.log'
local util = require 'gitano.util'
local repository = require 'gitano.repository'

local unpack = table.unpack or unpack

local builtin_gc_short = "Invoke git gc on your repository"
local builtin_gc_helptext = [[
usage: gc repo [options]

Invoke, git gc, passing the given options, on the given repository.
You must have basic write access to the repository in order to invoke a gc.
]]

local function builtin_gc_prep(config, repo, cmdline, context)
   context.operation = "write"
   return repo:run_lace(context)
end

local builtin_count_objects_short = "Count objects in your projects"
local builtin_count_objects_helptext = [[
usage: count-objects repo [options]

Counts objects in your repository.

You must have read access to the repository in order
to run count-objects.
]]

local function builtin_count_objects_prep(config, repo, cmdline, context)
   context.operation = "read"
   return repo:run_lace(context)
end

local builtin_fsck_short = "Perform a fsck operation on a repository"
local builtin_fsck_helptext = [[
usage: fsck repo [options]

Runs the git fsck process in your repository.

You must have write access to the repository in order
to run fsck.
]]

local function builtin_fsck_prep(config, repo, cmdline, context)
   context.operation = "write"
   return repo:run_lace(context)
end

local function builtin_simple_validate(config, repo, cmdline)
   if not repo or repo.is_nascent then
      log.error("Unable to proceed, repository does not exist")
      return false
   end
   return true
end

local function builtin_simple_run(config, repo, cmdline, env)
   local cmdcopy = {cmdline[1]}
   for i = 3, #cmdline do cmdcopy[#cmdcopy+1] = cmdline[i] end
   local why, stdout, stderr = repo.git:rawgather(unpack(cmdcopy))
   if stdout ~= "" then
      log.stdout(stdout)
   end
   if stderr ~= "" then
      log.state(stderr)
   end
   return "exit", why
end

local function register_repocommand(register_cmd)
   assert(register_cmd("gc", builtin_gc_short, builtin_gc_helptext,
                       builtin_simple_validate, builtin_gc_prep,
                       builtin_simple_run, true, false))

   assert(register_cmd("count-objects", builtin_count_objects_short,
                       builtin_count_objects_helptext, builtin_simple_validate,
                       builtin_count_objects_prep, builtin_simple_run,
                       true, false))

   assert(register_cmd("fsck", builtin_fsck_short, builtin_fsck_helptext,
                       builtin_simple_validate, builtin_fsck_prep,
                       builtin_simple_run, true, false))
end

return {
   register = register_repocommand
}
