--------------------------------------------------------------------------------
--  Copyright (c) 2011-2012 Sierra Wireless.
--  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:
--      Simon BERNARD <sbernard@sierrawireless.com>
--          - initial API and implementation and initial documentation
--------------------------------------------------------------------------------
-{ extension ('match', ...) }

local Q = require 'metalua.treequery'

local internalmodel = require 'models.internalmodel'
local apimodel = require 'models.apimodel'
local apimodelbuilder = require 'models.apimodelbuilder'

local M = {}

-- Analyzes an AST and returns two tables
-- * `locals`, which associates `Id{ } nodes which create a local variable
--   to a list of the `Id{ } occurrence nodes of that variable;
-- * `globals` which associates variable names to occurrences of
--   global variables having that name.
function bindings(ast)
  local locals, globals = { }, { }
  local function f(id, ...)
    local name = id[1]
    if Q.is_binder(id, ...) then
      local binder = ... -- parent is the binder
      locals[binder] = locals[binder] or { }
      locals[binder][name]={ }
    else
      local _, binder = Q.get_binder(id, ...)
      if binder then -- this is a local
        table.insert(locals[binder][name], id)  
     else
        local g = globals[name]
        if g then table.insert(g, id) else globals[name]={id} end
      end
    end
  end
  Q(ast) :filter('Id') :foreach(f)
  return locals, globals
end

-- --------------------------------------

-- ----------------------------------------------------------
-- return the comment linked before to this node
-- ----------------------------------------------------------
local function getlinkedcommentbefore(node)
  local function _getlinkedcomment(node,line)
    if node and node.lineinfo and node.lineinfo.first.line == line then
      -- get the last comment before (the nearest of code)
      local comments = node.lineinfo.first.comments
      local comment = comments and  comments[#comments]
      if comment  and comment.lineinfo.last.line == line-1 then
        -- ignore the comment if there are code before on the same line
        if node.lineinfo.first.facing and (node.lineinfo.first.facing.line ~= comment.lineinfo.first.line) then
          return comment
        end
      else
        return _getlinkedcomment(node.parent,line)
      end
    end
    return nil  
  end
  
  if node.lineinfo and node.lineinfo.first.line then
    return _getlinkedcomment(node,node.lineinfo.first.line)
  else
    return nil
  end
end

-- ----------------------------------------------------------
-- return the comment linked after to this node
-- ----------------------------------------------------------
local function getlinkedcommentafter(node)
  local function _getlinkedcomment(node,line)
    if node and node.lineinfo and node.lineinfo.last.line == line then
      -- get the first comment after (the nearest of code)
      local comments = node.lineinfo.last.comments
      local comment = comments and  comments[1] 
      if comment  and comment.lineinfo.first.line == line then
        return comment
      else
        return _getlinkedcomment(node.parent,line)
      end
    end
    return nil  
  end
  
  if node.lineinfo and node.lineinfo.last.line then
    return _getlinkedcomment(node,node.lineinfo.last.line)
  else
    return nil
  end
end

-- ----------------------------------------------------------
-- return true if this node is a block for the internal representation
-- ----------------------------------------------------------
local supported_b = {
  Function = true,
  Do       = true,
  While    = true,
  Fornum   = true,
  Forin    = true,
  Repeat   = true,
}
local function supportedblock(node, parent)
  return supported_b[ node.tag ] or
    (parent and parent.tag == "If" and node.tag == nil)
end

-- ----------------------------------------------------------
-- create a block from the  metalua node
-- ----------------------------------------------------------
local function createblock(block, parent)
  local _block =  internalmodel._block()
  match block with
    | `Function{param, body}
    | `Do{...}
    | `Fornum {...}
    | `Forin {identifiers, exprs, body}
    | `Repeat {body, expr} ->
        _block.sourcerange.min = block.lineinfo.first.offset
        _block.sourcerange.max = block.lineinfo.last.offset
    | `While {expr, body} ->
        _block.sourcerange.min = body.lineinfo.first.facing.offset
        _block.sourcerange.max = body.lineinfo.last.facing.offset
    | _ ->
        if parent and parent.tag == "If" and block.tag == nil then
          _block.sourcerange.min = block.lineinfo.first.facing.offset
          _block.sourcerange.max = block.lineinfo.last.facing.offset
        end
  end
  return _block
end

-- ----------------------------------------------------------
-- return true if this node is a expression in the internal representation
-- ----------------------------------------------------------
local supported_e = {
  Index  = true,
  Id     = true,
  Call   = true,
  Invoke = true
}
local function supportedexpr(node)
  return supported_e[ node.tag ]
end

local idto_block = {} -- cache from metalua id to internal model block 
local idto_identifier = {} -- cache from  metalua id to internal model indentifier
local expreto_expression = {} -- cache from  metalua expression to internal model expression

-- ----------------------------------------------------------
-- create an expression from a metalua node
-- ----------------------------------------------------------
local function createexpr(expr,_block)
  local _expr = nil 
  
  match expr with
    | `Id { name } ->
        -- we store the block which hold this node 
        -- to be able to define  
        idto_block[expr]= _block
  
        -- if expr has not line info, it means expr has no representation in the code
        -- so we don't need it.
        if not expr.lineinfo then  return nil end
        
        -- create identifier
        local _identifier = internalmodel._identifier()
        idto_identifier[expr]= _identifier
        _expr =  _identifier
    | `Index { innerexpr, rightpart } ->
        if not expr.lineinfo then  return nil end
        -- create index
        local _expression = createexpr(innerexpr,_block)
        if _expression then
          if rightpart and rightpart.tag=='String' then
            _expr =  internalmodel._index(_expression,rightpart[1])
          else
            _expr = internalmodel._index(_expression,nil)
          end
        end
    | `Call{innerexpr, ...} ->
        if not expr.lineinfo then  return nil end
        -- create call 
        local _expression = createexpr(innerexpr,_block)
        if _expression then _expr =  internalmodel._call(_expression) end
    | `Invoke{innerexpr,`String{functionname},...} ->
        if not expr.lineinfo then  return nil end
        -- create invoke
        local _expression = createexpr(innerexpr,_block)
        if _expression then _expr = internalmodel._invoke(functionname,_expression) end
    | _ ->
  end
  
  if _expr then
    _expr.sourcerange.min = expr.lineinfo.first.offset 
    _expr.sourcerange.max = expr.lineinfo.last.offset

    expreto_expression[expr] = _expr
  end
  
  return _expr
end

-- ----------------------------------------------------------
-- create block and expression node
-- ----------------------------------------------------------
local function createtreestructure(ast)
  -- create internal content 
  local _internalcontent = internalmodel._internalcontent()

  -- create root block
  local _block = internalmodel._block()
  local _blocks = { _block }
  _block.sourcerange.min = ast.lineinfo.first.facing.offset
  -- TODO remove the math.max when we support partial AST
  _block.sourcerange.max = math.max(ast.lineinfo.last.facing.offset, 10000)

  _internalcontent.content = _block
  
  -- visitor function (down)
  local function down (node,parent)
    if supportedblock(node,parent) then
      -- create the block
      local _block = createblock(node,parent)
      -- add it to parent block
      table.insert(_blocks[#_blocks].content, _block) 
      -- enqueue the last block to know the "current" block
      table.insert(_blocks,_block)
    elseif supportedexpr(node) then
      -- we handle expression only if it was not already do
      if not  expreto_expression[node] then
        -- create expr
        local _expression = createexpr(node,_blocks[#_blocks])
        -- add it to parent block
        if _expression then
          table.insert(_blocks[#_blocks].content, _expression)
        end  
      end
    end
  end
  
  -- visitor function (up)
  local function up (node, parent)
    if supportedblock(node,parent) then
      -- dequeue the last block to know the "current" block
      table.remove(_blocks,#_blocks)
    end    
  end
 
  -- visit ast and build internal model  
  Q(ast):foreach(down,up)
      
  return _internalcontent
end

local getitem

-- ----------------------------------------------------------
-- create the type from the node and position
-- ----------------------------------------------------------
local function createtype(node,position,comment2apiobj,file)
  -- create module type ref
  match node with
    | `Call{ `Id "require", `String {modulename}} ->
        return apimodel._moduletyperef(modulename,position)
    | `Function {params, body} ->
        -- create the functiontypedef from code
        local _functiontypedef = apimodel._functiontypedef()
        for _, p in ipairs(params) do
          -- create parameters
          local paramname
          if p.tag=="Dots" then
            paramname = "..."
          else
            paramname = p[1]
          end
          local _param = apimodel._parameter(paramname)
          table.insert(_functiontypedef.params,_param)
        end
        _functiontypedef.name = "___" -- no name for inline type
        
        return apimodel._inlinetyperef(_functiontypedef)
    | `String {value} ->
        local typeref = apimodel._primitivetyperef("string")
        return typeref
    | `Number {value} ->
        local typeref = apimodel._primitivetyperef("number")
        return typeref
    | `True | `False ->
        local typeref = apimodel._primitivetyperef("boolean")
         return typeref
    | `Table {...} ->
        -- create recordtypedef  from code
        local _recordtypedef = apimodel._recordtypedef("table")
        -- for each element of the table
        for i=1,select("#", ...) do
              local pair = select(i, ...)
              -- if this is a pair we create a new item in the type
          if pair.tag == "Pair" then
            -- create an item
            local _item = getitem(pair,nil, comment2apiobj,file)
            if _item then
              _recordtypedef:addfield(_item)
            end
          end
        end        
        return apimodel._inlinetyperef(_recordtypedef)
    | _ ->
  end
  -- if node is an expression supported
  local supportedexpr = expreto_expression[node]
  if supportedexpr then
    -- create expression type ref
    return apimodel._exprtyperef(supportedexpr,position)
  end
  
end

local function completeapidoctype(apidoctype,itemname,init,file,comment2apiobj)
  if not apidoctype.name then
    apidoctype.name = itemname
    file:mergetype(apidoctype)
  end
  
  -- create type from code
  local typeref = createtype(init,1,comment2apiobj,file)
  if typeref and typeref.tag == "inlinetyperef" 
    and typeref.def.tag == "recordtypedef" then
    
    -- set the name
    typeref.def.name = apidoctype.name
    
    -- merge the type with priority to documentation except for source range
    file:mergetype(typeref.def,false,true)
  end
end

local function completeapidocitem (apidocitem, itemname, init, file, binder, comment2apiobj)
  -- manage the case item has no name
  if not apidocitem.name then 
    apidocitem.name = itemname
    
    -- if item has no name this means it could not be attach to a parent
    if apidocitem.scope then 
      apimodelbuilder.additemtoparent(file,apidocitem,apidocitem.scope,apidocitem.sourcerange.min,apidocitem.sourcerange.max)
      apidocitem.scope = nil
    end
  end        

  -- for function try to merge definition
  local apitype = apidocitem:resolvetype(file)
  if apitype and apitype.tag == "functiontypedef" then
    local codetype = createtype(init,1,comment2apiobj,file)
    if codetype and codetype.tag =="inlinetyperef" then
      codetype.def.name = apitype.name
      file:mergetype(codetype.def)
    end
  end
  
  -- manage the case item has no type
  if not apidocitem.type then
    -- extract typing from comment
    local type, desc = apimodelbuilder.extractlocaltype(getlinkedcommentafter(binder),file)
    
    if type then
      apidocitem.type = type
    else
      -- if not found extracttype from code 
      apidocitem.type = createtype(init,1,comment2apiobj,file)
    end
    
    local apitype = apidocitem:resolvetype(file)
    if apitype and apitype.tag == "functiontypedef" and apidocitem.metadata then
      apitype.metadata = apidocitem.metadata
    end
  end
end

-- ----------------------------------------------------------
-- create or get the item finding in the binder with the given itemname
-- return also the ast node corresponding to this item  
-- ----------------------------------------------------------
getitem = function (binder, itemname, comment2apiobj, file)
   
   -- local function to create item 
  local function createitem(itemname, astnode, itemtype, description)
    local _item = apimodel._item(itemname)
    if description then _item.description = description end
    _item.type = itemtype
    if astnode and astnode.lineinfo then 
      _item.sourcerange.min = astnode.lineinfo.first.offset 
      _item.sourcerange.max = astnode.lineinfo.last.offset 
    end
    return _item, astnode
  end
  
  -- try to match binder with known patter of item declaration    
  match binder with
    | `Pair  {string, init}
    | `Set   { {`Index { right , string}}, {init,...}} if string and string.tag =="String" ->
      -- Pair and set is for searching field from type ..
      -- if the itemname is given this mean we search for a local or a global not a field type.
      if not itemname then
        local itemname = string[1]
      
        -- check for luadoc typing
        local commentbefore = getlinkedcommentbefore(binder)
        local apiobj = comment2apiobj[commentbefore] -- find apiobj linked to this comment
        if apiobj then
          if apiobj.tag=="item" then
            if not apiobj.name or apiobj.name == itemname then
              -- use code to complete api information if it's necessary
              completeapidocitem(apiobj, itemname, init,file,binder,comment2apiobj)
              -- for item use code source range rather than doc source range
              if string and string.lineinfo then
                apiobj.sourcerange.min =  string.lineinfo.first.offset
                apiobj.sourcerange.max = string.lineinfo.last.offset
              end              
              return apiobj, string          
            end
          elseif apiobj.tag=="recordtypedef" then
            -- use code to complete api information if it's necessary
            completeapidoctype(apiobj, itemname, init,file,comment2apiobj)
            return createitem(itemname, string, apimodel._internaltyperef(apiobj.name), nil)
          end
          
          -- if the apiobj could not be associated to the current obj, 
          -- we do not use the documentation neither
          commentbefore = nil
        end
                
        -- else we use code to extract the type and description
        -- check for "local" typing
          local type, desc = apimodelbuilder.extractlocaltype(getlinkedcommentafter(binder),file)
          local desc = desc or (commentbefore and commentbefore[1])
        if type then
          return createitem(itemname, string, type, desc ) 
        else
          -- if no "local typing" extract type from code
          return createitem(itemname, string, createtype(init,1,comment2apiobj,file), desc)
        end
      end
  | `Set {ids, inits} 
  | `Local {ids, inits} ->
      -- if this is a single local var declaration
      -- we check if there are a comment block linked and try to extract the type
      if #ids == 1 then
        local currentid, currentinit = ids[1],inits[1]
        -- ignore non Ids node
        if currentid.tag ~= 'Id' or currentid[1] ~= itemname then return nil end

          -- check for luadoc typing
        local commentbefore = getlinkedcommentbefore(binder)
        local apiobj = comment2apiobj[commentbefore] -- find apiobj linked to this comment
        if apiobj then
          if apiobj.tag=="item" then
            -- use code to complete api information if it's necessary
            if not apiobj.name or apiobj.name == itemname then 
              completeapidocitem(apiobj, itemname, currentinit,file,binder,comment2apiobj)
              -- if this is a global var or if is has no parent
              -- we do not create a new item
              if not apiobj.parent or apiobj.parent == file  then
                -- for item use code source range rather than doc source range
                if currentid and currentid.lineinfo then
                  apiobj.sourcerange.min = currentid.lineinfo.first.offset
                  apiobj.sourcerange.max = currentid.lineinfo.last.offset
                end  
                return apiobj, currentid
              else
                return createitem(itemname, currentid, apiobj.type, nil)
              end          
            end
          elseif apiobj.tag=="recordtypedef" then
            -- use code to complete api information if it's necessary
            completeapidoctype(apiobj, itemname, currentinit,file,comment2apiobj)
            return createitem(itemname, currentid, apimodel._internaltyperef(apiobj.name), nil)
          end

          -- if the apiobj could not be associated to the current obj, 
          -- we do not use the documentation neither
          commentbefore = nil
        end
                
        -- else we use code to extract the type and description
        -- check for "local" typing
        local type,desc = apimodelbuilder.extractlocaltype(getlinkedcommentafter(binder),file)
          desc = desc or (commentbefore and commentbefore[1])
        if type then 
          return createitem(itemname, currentid, type, desc) 
        else
          -- if no "local typing" extract type from code
          return createitem(itemname, currentid, createtype(currentinit,1,comment2apiobj,file), desc)
        end
      end
      -- else we use code to extract the type      
      local init,returnposition = nil,1
      for i,id in ipairs(ids) do
        -- calculate the current return position
        if init and (init.tag == "Call" or init.tag == "Invoke") then
          -- if previous init was a call or an invoke
          -- we increment the returnposition
          returnposition= returnposition+1
        else
          -- if init is not a function call
          -- we change the init used to determine the type 
          init = inits[i]                  
        end
        
        -- get the name of the current id
        local idname = id[1] 
        
        -- if this is the good id
        if itemname == idname then
          -- create type from init node and return position
          return createitem (itemname, id, createtype(init,returnposition,comment2apiobj,file),nil)
        end
      end
  | `Function {params, body} ->
      for i,id in ipairs(params) do
        -- get the name of the current id
        local idname = id[1]
        -- if this is the good id
        if itemname == idname then
          -- extract param's type  from luadocumentation
          local obj = comment2apiobj[getlinkedcommentbefore(binder)]
          if obj and obj.tag=="item" then
            local typedef = obj:resolvetype(file)
            if typedef and typedef.tag =="functiontypedef" then 
              for j, param in ipairs(typedef.params) do
                if i==j then
                  if i ==1 and itemname == "self"  and param.type == nil 
                    and obj.parent and obj.parent.tag == "recordtypedef" and obj.parent.name then
                    param.type = apimodel._internaltyperef(obj.parent.name)
                  end
                  -- TODO perhaps we must clone the typeref
                  return createitem(itemname,id, param.type,param.description)
                end
              end
            end
          else
            -- this is the case where we have
            -- function expr.f(self) or  function expr:f()
            -- we suppose the type of self is the type of "expr" 
            if itemname == "self" and i==1 and binder.parent.tag == "Set" then
              match binder.parent with
              |`Set   { {`Index { right , string}}, {...}} ->
                  -- if node is an expression supported
                  local supportedexpr = expreto_expression[right]
                  if supportedexpr then
                    -- create expression type ref
                    local selftype = apimodel._exprtyperef(supportedexpr,1)
                    return createitem(itemname,id,selftype)
                  end
              end
            end
          end              
          return createitem(itemname,id)
        end
      end
  | `Forin {ids, expr, body} ->
      for i,id in ipairs(ids) do
        -- get the name of the current id
        local idname = id[1]
        -- if this is the good id
        if itemname == idname then
          -- return data : we can not guess the type for now
          return createitem(itemname,id)
        end
      end  
  | `Fornum {id, ...} ->
      -- get the name of the current id
      local idname = id[1]
      -- if this is the good id
      if itemname == idname then
        -- return data : we can not guess the type for now
        return createitem(itemname,id)
      end          
  | `Localrec {{id}, {func}} ->
      -- get the name of the current id
      local idname = id[1]
      -- if this is the good id
      if itemname == idname then
        -- check for luadoc typing
        local commentbefore = getlinkedcommentbefore(binder)
        local apiobj = comment2apiobj[commentbefore] -- find apiobj linked to this comment
        if apiobj then
          if apiobj.tag=="item" then
            if not apiobj.name or apiobj.name == itemname then
              -- use code to complete api information if it's necessary
              completeapidocitem(apiobj, itemname, func,file,binder,comment2apiobj)
              return createitem(itemname,id,apiobj.type,nil)
            end
          end
      
          -- if the apiobj could not be associated to the current obj, 
          -- we do not use the documentation neither
          commentbefore = nil
        end
          
        -- else we use code to extract the type and description
        -- check for "local" typing
        local type,desc = apimodelbuilder.extractlocaltype(getlinkedcommentafter(binder),file)
          desc = desc or (commentbefore and commentbefore[1])
          if type then 
          return createitem(itemname, id, type, desc) 
        else
          -- if no "local typing" extract type from code
          return createitem(itemname, id, createtype(func,1,comment2apiobj,file), desc)
        end
      end            
  | _ ->
  end
end

-- ----------------------------------------------------------
-- Search from Id node to Set node to find field of type.
--
-- Lua code : table.field1.field2 = 12
-- looks like that in metalua :  
--      `Set{ 
--            `Index { `Index { `Id "table", `String "field1" },
--                     `String "field2"},
--            `Number "12"} 
-- ----------------------------------------------------------
local function searchtypefield(node,_currentitem,comment2apiobj,file)
  
  -- we are just interested : 
  -- by item which is field of recordtypedef
  -- by ast node which are Index
  if _currentitem then
    local type = _currentitem:resolvetype(file)
    if type and type.tag == "recordtypedef" then
      if node and node.tag == "Index" then
        local rightpart = node[2]
        local _newcurrentitem = type.fields[rightpart[1]]
        
        if _newcurrentitem then
          -- if this index represent a known field of the type we continue to search 
          searchtypefield (node.parent,_newcurrentitem,comment2apiobj,file)
        else
          -- if not, this is perhaps a new field, but
          -- to be a new field this index must be include in a Set
          if node.parent and node.parent.tag =="Set" then
            -- in this case we create the new item ans add it to the type
            local set = node.parent
            local item, string = getitem(set,nil, comment2apiobj,file)
            -- add this item to the type, only if it has no parent and if this type does not contain already this field
            if item and not item.parent and string and not type.fields[string[1]]  then
              type:addfield(item)
            end                    
          end
        end        
      end
    end  
  end
end 

-- ----------------------------------------------------------
-- create local vars, global vars and linked it with theirs occurences
-- ----------------------------------------------------------
local function createvardefinitions(_internalcontent,ast,file,comment2apiobj)
  -- use bindings to get locals and globals definition
  local locals, globals = bindings( ast )
  
  -- create locals var
  for binder, namesAndOccurrences in pairs(locals) do
    for name, occurrences in pairs(namesAndOccurrences) do
      -- get item, id 
      local _item, id = getitem(binder, name,comment2apiobj,file)
      if id then
        -- add definition as occurence
        -- we consider the identifier in the binder as an occurence
        local _identifierdef = idto_identifier[id]
        if _identifierdef then
          table.insert(_item.occurrences, _identifierdef)
          _identifierdef.definition = _item
        end
          
        -- add occurences
        for _,occurrence in ipairs(occurrences) do
          searchtypefield(occurrence.parent, _item,comment2apiobj,file)
          local _identifier = idto_identifier[occurrence]
          if _identifier then
            table.insert(_item.occurrences, _identifier)
            _identifier.definition = _item 
          end 
        end
      
        -- add item to block
        local _block = idto_block[id]
        table.insert(_block.localvars,{item=_item,scope = {min=0,max=0}})
      end  
    end
  end
  
  -- create globals var
  for name, occurrences in pairs( globals ) do
    
    -- get or create definition
    local _item = file.globalvars[name]
    local binder = occurrences[1].parent
    if not _item then
      -- global declaration is only if the first occurence in left part of a 'Set'
      if binder and binder.tag == "Set" then
         _item = getitem(binder, name,comment2apiobj,file)
      end
      
      -- if we find and item this is a global var declaration
      if _item then
        file:addglobalvar(_item)
      else
        -- else it is an unknown global var
        _item = apimodel._item(name)
        local _firstoccurrence = idto_identifier[occurrences[1]]
        if _firstoccurrence then
          _item.sourcerange.min = _firstoccurrence.sourcerange.min
          _item.sourcerange.max = _firstoccurrence.sourcerange.max
        end
        table.insert(_internalcontent.unknownglobalvars,_item)
      end
    else
      -- if the global var definition already exists, we just try to it 
      if binder then
        match binder with
          | `Set {ids, inits} ->
              -- manage case only if there are 1 element in the Set
              if #ids == 1 then
                local currentid, currentinit = ids[1],inits[1]
                -- ignore non Ids node and bad name
                if currentid.tag == 'Id' and currentid[1] == name then
                  completeapidocitem(_item, name, currentinit,file,binder,comment2apiobj)
                  
                  if currentid and currentid.lineinfo then
                    _item.sourcerange.min = currentid.lineinfo.first.offset
                    _item.sourcerange.max = currentid.lineinfo.last.offset
                  end
                end
              end
          | _ ->
        end
      end
    end

    -- add occurences
    for _,occurence in ipairs(occurrences) do
      local _identifier = idto_identifier[occurence]
      searchtypefield(occurence.parent, _item,comment2apiobj,file)
      if _identifier then
        table.insert(_item.occurrences, _identifier)
        _identifier.definition = _item 
      end 
    end
  end
end

-- ----------------------------------------------------------
-- add parent to all ast node
-- ----------------------------------------------------------
local function addparents(ast)
  -- visitor function (down)
  local function down (node,parent)
    node.parent = parent
  end

  -- visit ast and build internal model  
  Q(ast):foreach(down,up)
end

-- ----------------------------------------------------------
-- try to detect a module declaration from code
-- ----------------------------------------------------------
local function searchmodule(ast,file,comment2apiobj,modulename)
  -- if the last statement is a return
  if ast then
    local laststatement = ast[#ast]
    if laststatement and laststatement.tag == "Return" then
      -- and if the first expression returned is an identifier.
      local firstexpr = laststatement[1]
      if firstexpr and firstexpr.tag == "Id" then
        -- get identifier in internal model
        local _identifier = idto_identifier [firstexpr]
        -- the definition should be an inline type
        if      _identifier 
            and _identifier.definition 
          and _identifier.definition.type 
          and _identifier.definition.type.tag == "inlinetyperef"
          and _identifier.definition.type.def.tag == "recordtypedef" then
          
          --set modulename if needed
          if not file.name then file.name = modulename end
          
          -- create or merge type
          local _type = _identifier.definition.type.def
          _type.name = modulename
          
          -- if file (module) has no documentation add item documentation to it
          -- else add it to the type.
          if not file.description or file.description == "" then
            file.description = _identifier.definition.description
          else
            _type.description = _identifier.definition.description
          end
          _identifier.definition.description = ""
          if not file.shortdescription or file.shortdescription == ""  then
            file.shortdescription = _identifier.definition.shortdescription
          else
            _type.shortdescription = _identifier.definition.shortdescription
          end
          _identifier.definition.shortdescription = ""
          
          _type.sourcerange.min = _identifier.definition.sourcerange.min
          _type.sourcerange.max = _identifier.definition.sourcerange.max
          
          -- merge the type with priority to documentation except for source range
          file:mergetype(_type,false,true)
          
          -- create return if needed
          if not file.returns[1] then
            file.returns[1] = apimodel._return()
            file.returns[1].types = { apimodel._internaltyperef(modulename) }
          end
            
          -- change the type of the identifier
          _identifier.definition.type = apimodel._internaltyperef(modulename)
        end
      end  
    end
  end
end

-- ----------------------------------------------------------
-- create the internalcontent from an ast metalua
-- ---------------------------------------------------------- 
function M.createinternalcontent (ast,file,comment2apiobj,modulename)
  -- init cache
  idto_block = {}  
  idto_identifier = {} 
  expreto_expression = {}
  comment2apiobj = comment2apiobj or {}
  file = file or apimodel._file()
    
  -- execute code safely to be sure to clean cache correctly
  local internalcontent  
  local ok, errmsg = pcall(function ()   
    -- add parent to all node 
    addparents(ast)
    
    -- create block and expression node
    internalcontent = createtreestructure(ast)
    
    -- create Local vars, global vars and linked occurences (Items)
    createvardefinitions(internalcontent,ast,file,comment2apiobj)
    
    -- try to dectect module information from code 
    local moduletyperef = file:moduletyperef()
    if moduletyperef and moduletyperef.tag == "internaltyperef" then
      modulename  = moduletyperef.typename or modulename
    end
    if modulename then
      searchmodule(ast,file,comment2apiobj,modulename)
    end
  end)
  
  -- clean cache
  idto_block = {}  
  idto_identifier = {} 
  expreto_expression = {}
  
  -- if not ok raise an error
  if not ok then error (errmsg) end 
  
  return internalcontent
end

return M 
