-- ----------------------------------------------------------------------------
-- Copyright (c) 2011-2012 Sierra Wireless and others.
-- All rights reserved. This program and the accompanying materials
-- are made available under the terms of the Eclipse Public License v1.0
-- which accompanies this distribution, and is available at
-- http://www.eclipse.org/legal/epl-v10.html
--
-- Contributors:
--     Julien Desgats - initial API and implementation
-- ----------------------------------------------------------------------------
-- Properties generation. Generate a LOM table with data from introspection.
-- ----------------------------------------------------------------------------

local debug = require "debug"
local platform = require "debugger.platform"
local util = require "debugger.util"

local tostring, type, assert, next, rawget, getmetatable, setmetatable, getfenv, select,         coyield,         cocreate,         costatus,         coresume,       sformat,      tconcat =
  tostring, type, assert, next, rawget, getmetatable, setmetatable, getfenv, select, coroutine.yield, coroutine.create, coroutine.status, coroutine.resume, string.format, table.concat

local MULTIVAL_MT = { __tostring = function() return "" end }
local probes = { }

-- ---------- --
-- Public API --
-- ---------- --

---
-- Introspection logic. This module implements Lua objects introspection and
-- generates a [DBGP](http://xdebug.org/docs-dbgp.php) compatible
-- [LOM](http://matthewwild.co.uk/projects/luaexpat/lom.html) data scructure.
-- @module debugger.introspection
local M = { }

---
-- Represent the actual data to send to the debugger.
-- Full XML specification can be found in [DBGP specification](http://xdebug.org/docs-dbgp.php#properties-variables-and-values).
-- Modifying properties after their generation is possible (as actual data serialization/sending is delayed)
-- but should be used with care. The XML structure uses the [LOM](http://matthewwild.co.uk/projects/luaexpat/lom.html)
-- format, refer to these documents to get more informations about fields.
--
-- In addition to table fields, it has an array part, `[1]` being the string representation (base64 encoded),
-- possibly followed by chlid properties (@{#DBGPProperty} themselves)
--
-- @field #string tag Always "property"
-- @field #table attr XML attributes, see DBGP specification
-- @type DBGPProperty

---
-- Inpectors table, contain all inspector functions.
-- Keys are either type names (`string`, `number`, ...) or metatables
-- that have a custom inspector attached.
-- @field [parent=#debugger.introspection] #table inspectors
M.inspectors = { }

---
-- Generate a DBGP property if needed. If data is in data pagination and recursion depth ranges,
-- and send a property to the debugger, otherwise drop current property.
-- @param #string name Property name (displayed in IDE)
-- @param #string typename Type name (displayed in IDE)
-- @param #string repr Value string representation
-- @param #DBGPProperty parent Parent property
-- @param #string fullname Lua expression used to get value back in further calls
-- @return #table description
-- @function [parent=#debugger.introspection] property
M.property = coyield

---
-- Adds a probe that will be called for every unknown table/userdata.
-- @param #function probe Inspector function to call.
-- @function [parent=#debugger.introspection] add_probe
M.add_probe = function(probe) probes[#probes + 1] = probe end

---
-- Inspects a Lua value by dispatching it to correct inspector. Inspector functions have the same API.
-- @param #string name Property name (will be displayed by IDE)
-- @param value Value to inspect
-- @param #table parent Parent property (LOM table of the )
-- @param #string fullname Expression used to retrieve `value` for further debugger calls
-- @return #DBGPProperty The inspected value as returned by @{debugger.introspection#debugger.introspection.property}.
-- @return #nil If the value has not been inspected
-- @function [parent=#debugger.introspection] inspect
M.inspect = function(name, value, parent, fullname)
  return (M.inspectors[type(value)] or M.inspectors.default)(name, value, parent, fullname)
end

-- ----------------- --
-- Utility functions --
-- ----------------- --

local function default_inspector(name, value, parent, fullname)
  return M.property(name, type(value), tostring(value), parent, fullname)
end

-- Inspects types that can have a metatable (table and userdata). Returns
--   1) generated property
--   2) boolean indicating whether a custom inspector has been called (in that case, do not process value any further)
local function metatable_inspector(name, value, parent, fullname)
  local mt = getmetatable(value)
  do
    -- find  by metatable
    local custom = M.inspectors[mt]
    if custom then return custom(name, value, parent, fullname), true end
    -- or else call probes
    for i=1, #probes do
      local prop = probes[i](name, value, parent, fullname)
      if prop then return prop, true end
    end
  end

  local prop = default_inspector(name, value, parent, fullname)
  if mt and prop then
    local mtprop = M.inspect("metatable", mt, prop, "metatable["..prop.attr.fullname.."]")
    if mtprop then mtprop.attr.type = "special" end
  end
  return prop, false
end

local function fancy_func_repr(f, info)
  local args = {}
  for i=1, info.nparams do
    args[i] = debug.getlocal(f, i)
  end

  if info.isvararg then
    args[#args+1] = "..."
  end

  return "function(" .. tconcat(args, ", ") .. ")"
end

--- Generate a name siutable for table index syntax
-- @param name Key name
-- @return #string A table index style index
-- @usage generate_printable_key('foo') => '["foo"]'
-- @usage generate_printable_key(12)    => '[12]'
-- @usage generate_printable_key({})    => '[table: 0x12345678]
-- @function [parent=#debugger.introspection] generate_printable_key
local function generate_printable_key(name)
  return "[" .. (type(name) == "string" and sformat("%q", name) or tostring(name)) .. "]"
end
M.generate_printable_key = generate_printable_key

-- Used to store complex keys (other than string and number) as they cannot be passed in text
-- For these keys, the resulting expression will not be the key itself but "key_cache[...]"
-- where key_cache must be mapped to this table to resolve key correctly.
M.key_cache = setmetatable({ n=0 }, { __mode = "v" })

local function generate_key(name)
  local tname = type(name)
  if tname == "string" then return sformat("%q", name)
  elseif tname == "number" or tname == "boolean" then return tostring(name)
  else -- complex key, use key_cache for lookup
    local i = M.key_cache.n
    M.key_cache[i] = name
    M.key_cache.n = i+1
    return "key_cache["..tostring(i).."]"
  end
end

--- Generate a usable fullname for a value.
-- Based on parent fullname and key value, return a valid Lua expression.
-- Key can be any value (as anything can act as table key). If it cannot
-- be serialized (only string, number and boolean can), it will be temporarly
-- stored in an internal cache to be retrieved later.
-- @param #string parent Parent fullname
-- @param key The child key to generate fullname for
-- @return #string A valid fullname expression
-- @function [parent=#debugger.introspection] make_fullname
local function make_fullname(parent, key)
  return parent .. "[" .. generate_key(key) .. "]"
end
M.make_fullname = make_fullname

-- ---------- --
-- Inspectors --
-- ---------- --

M.inspectors.number   = default_inspector
M.inspectors.boolean  = default_inspector
M.inspectors["nil"]   = default_inspector
M.inspectors.userdata = default_inspector
M.inspectors.thread   = default_inspector
M.inspectors.default  = default_inspector -- allows 3rd party inspectors to use the default inspector if needed

M.inspectors.userdata = function(name, value, parent, fullname)
  return (metatable_inspector(name, value, parent, fullname)) -- drop second return value
end

M.inspectors.string = function(name, value, parent, fullname)
  -- escape linebreaks as \n and not as \<0x0A> like %q does
  return M.property(name, "string", sformat("%q", value):gsub("\\\n", "\\n"), parent, fullname)
end

M.inspectors["function"] = function(name, value, parent, fullname)
  local info = debug.getinfo(value, "nSflu")
  local prop
  if info.what ~= "C" then
    -- try to create a fancy representation if possible
    local repr = info.nparams and fancy_func_repr(value, info) or tostring(value)
    if info.source:sub(1,1) == "@" then
      repr = repr .. "\n" .. platform.get_uri("@" .. info.source) .. "\n" .. tostring(info.linedefined)
    end
    prop = M.property(name, "function (Lua)", repr, parent, fullname)
  else
    prop = M.property(name, "function", tostring(value), parent, fullname)
  end
  if not prop then return nil end

  -- (5.1 only) environment is dumped only if it is different from global environment
  -- TODO: this is not a correct behavior: environment should be dumped if is different from current stack level one
  local fenv = getfenv and getfenv(value)
  if fenv and fenv ~= getfenv(0) then
    local fenvprop = M.inspect("environment", fenv, prop, "environment["..prop.attr.fullname.."]")
    if fenvprop then fenvprop.attr.type = "special" end
  end

  return prop
end


M.inspectors.table = function(name, value, parent, fullname)
  local prop, iscustom = metatable_inspector(name, value, parent, fullname)
  if not prop or iscustom then return prop end

  -- iterate over table values and detect arrays at the same time
  -- next is used to circumvent __pairs metamethod in 5.2
  local isarray, i = true, 1
  for k,v in next, value, nil do
    M.inspect(generate_printable_key(k), v, prop, make_fullname(fullname, k))
    -- array detection: keys should be accessible by 1..n keys
    isarray = isarray and rawget(value, i) ~= nil
    i = i + 1
  end
  -- empty tables are considered as tables
  if isarray and i > 1 then prop.attr.type = "sequence" end

  return prop
end

M.inspectors[MULTIVAL_MT] = function(name, value, parent, fullname)
  if value.n == 1 then
    -- return directly the value as result
    return M.inspect(name, value[1], parent, fullname)
  else
    -- wrap values inside a multival container
    local prop = M.property(name, "multival", "", parent, fullname)
    if not prop then return nil end
    for i=1, value.n do
      M.inspect(generate_printable_key(i), value[i], prop, fullname .. "[" .. i .. "]")
    end
    return prop
  end
end

-- ------------ --
-- Internal API --
-- ------------ --

-- Used to inspect "multival" or "vararg" values. The typical use is to pack function result(s) in a single
-- value to inspect. The Multival instances can be passed to make_property as a single value, they will be
-- correctly reported to debugger
function M.Multival(...)
  return setmetatable({ n=select("#", ...), ... }, MULTIVAL_MT)
end

--- Makes a property form a name/value pair (and fullname). This is an **internal** function, and should not be used by 3rd party inspectors.
-- @param #number cxt_id Context ID in which this value resides (workaround bug 352316)
-- @param value The value to debug
-- @param name The name associated with value, passed through tostring, so it can be anything
-- @param #string fullname A Lua expression to eval to get that property again (if nil, computed automatically)
-- @param #number depth The maximum property depth (recursive calls)
-- @param #number pagesize maximum children to include
-- @param #number page The page to generate (0 based)
-- @param #number size_limit Optional, if set, the maximum size of the string representation (in bytes)
-- @param #boolean safe_name If true, does not encode the name as table key
-- @return #DBGPProperty root property
-- @function [parent=#debugger.introspection] make_property
--TODO BUG ECLIPSE TOOLSLINUX-99 352316 : as a workaround, context is encoded into the fullname property
M.make_property = function(cxt_id, value, name, fullname, depth, pagesize, page, size_limit, safe_name)
  fullname = fullname or "(...)[" .. generate_key(name) .. "]"
  if not safe_name then name = generate_printable_key(name) end

  local generator = cocreate(function() return M.inspect(name, value, nil, fullname) end)
  local propstack = { }
  local rootnode
  local catchthis = true
  local nodestoskip = page * pagesize -- nodes to skip at root level to respect pagination
  local fullname_prefix = tostring(cxt_id).."|"

  while true do
    local succes, name, datatype, repr, parent, fullname = assert(coresume(generator, catchthis and propstack[#propstack] or nil))
    -- finalize and pop all finished properties
    while propstack[#propstack] ~= parent do
      local topop = propstack[#propstack]
      topop.attr.fullname = util.rawb64(fullname_prefix .. topop.attr.fullname)
      propstack[#propstack] = nil
    end
    if costatus(generator) == "dead" then break end

    local prop = {
      tag = "property",
      attr = {
        children = 0,
        pagesize = pagesize,
        page = parent and 0 or page,
        type = datatype,
        name = name,
        fullname = fullname,
        encoding = "base64",
        size = #repr,
      },
      util.b64(size_limit and repr:sub(1, size_limit) or repr)
    }

    if parent then
      parent.attr.children = 1
      parent.attr.numchildren = (parent.attr.numchildren or 0) + 1
      -- take pagination into accont to know if node needs to be catched
      catchthis = #parent <= pagesize and #propstack <= depth
      if parent == rootnode then
        catchthis = catchthis and nodestoskip <= 0
        nodestoskip = nodestoskip - 1
      end
      -- add node to tree
      if catchthis then
        parent[#parent + 1] = prop
        propstack[#propstack + 1] = prop
      end
    else
      rootnode = prop
      catchthis = true
      propstack[#propstack + 1] = prop
    end
  end

  return rootnode
end

return M
