--[[

Copyright 2014-2015 The Luvit Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS-IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

--]]

local miniz = require('miniz')
local modes = require('git').modes
local log = require('log').log
local loadstring = loadstring or load

-- Create a zip from a hash optionally compiling lua files to bytecode.
return function (db, rootHash, compileLua)

  local writer = miniz.new_writer()

  local function importEntry(hash, path, mode)
    local kind, value = assert(db.loadAny(hash))
    mode = mode or modes[kind]
    if mode == modes.tree then
      if path then
        writer:add(path .. "/", "")
      end
      for i = 1, #value do
        local entry = value[i]
        local newPath = path and path .. '/' .. entry.name or entry.name
        importEntry(entry.hash, newPath, entry.mode)
      end
    elseif modes.isFile(mode) then
      if compileLua and path:find("%.lua$") then
        local fn = assert(loadstring(value, "bundle:" .. path))
        value = assert(string.dump(fn))
        log("compiling", path)
      else
        log("storing", path)
      end
      writer:add(path, value, 9)
    else
      error("Can't handle entry for " .. path)
    end
  end

  importEntry(rootHash)

  return writer:finalize()
end
