local format = string.format

local reap = require("lib.reap")

local BASE = reap.base_path(...)
local component_builder = require(format("%s.component", BASE))

local Concord = require("lib.Concord")

-- Modules
local Entity     = Concord.entity
local Component  = Concord.component
local System     = Concord.system
local World      = Concord.world

-- Containers
local Components  = Concord.components

local constructor = {}

--- build entity ecs
function constructor.new(system)
  if (type(system) == "table") then
    local e = Entity()
    for _, s in pairs(system) do
      for c, f in pairs(s.components) do
        if (type(c) == "string") then
          component_builder.component(c, f)
        else
          component_builder.state(f)
        end
      end
    end
    return e
  elseif (system == nil) then
    return Entity()
  else
    return nil
  end
end

--- ensure component
---@param entity any
---@param name string
function constructor.ensure(entity, name, ...)
  if (#{...} == 0) then
    component_builder.state(name)
    entity:ensure(name)
  else
    component_builder.component(name)
    entity:ensure(name, ...)
  end
end

--- give component
---@param entity any
---@param name string
function constructor.give(entity, name, ...)
  if (#{...} == 0) then
    component_builder.state(name)
    entity:give(name)
  else
    component_builder.component(name)
    entity:give(name, ...)
  end
end

function constructor.remove(entity, name)
  if Components.has(name) == false then
    return false, nil
  else
    if entity:has(name) then
      local data = entity[name]
      entity:remove(name)
      return true, data
    else
      return false, nil
    end
  end
end

function constructor.destroy(entity)
  local all_c = entity:getComponents()
  for c_id, c in ipairs(all_c) do
    entity:remove(c)
    print("destroy", c_id, c)
  end
  entity:destroy()
end

return constructor
