-------------------------------------------------------------------------------
-- Copyright (c) 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:
--     Sierra Wireless - initial API and implementation
-------------------------------------------------------------------------------
local formatter = require 'formatter'
local compiler = require 'metalua.compiler'
local mlc = compiler.new()
local Q = require 'metalua.treequery'
local M = {}
local cache
local function buildcache(str)

  -- Generate AST
  local ast = mlc:src_to_ast(str)
  local status, astvalid, errormsg = pcall(compiler.check_ast, ast)
  if not astvalid then
    return nil, string.format("Unable to build AST.%s", errormsg)
  end

  -- Cache string nodes
  cache = {}
  Q(ast):filter('String') :foreach(function(node)
    if node.tag == 'String' then
      table.insert(cache, node)
    end
  end)
  return true
end
local function mustbeignored(offset)
  if not cache then
    return nil, 'Cache is not available.'
  end
  for _, node in ipairs(cache) do
    if node.lineinfo.first.offset <= offset and offset <= node.lineinfo.last.offset then
      return true
    end
  end
  return false
end
function M.prettify(serializedtablestring)

  -- Check input
  if type(serializedtablestring) ~= 'string' then
    return nil, 'String expected.'
  end

  local chartoindent = {
    [','] = ',\n',
    [';'] = ';\n',
    ['{'] = '{\n',
    ['}'] = '\n}\n'
  }

  --
  -- Replace provided characters
  --
  for char, replacement in pairs(chartoindent) do

    -- Refresh cache as offset of analyzed string change at each loop
    local status, error = buildcache(serializedtablestring)
    if not status then
      return nil, error
    end

    --
    -- Seek for character to replace
    --
    local buffer = {}
    local searchstart= 1
    local charposition = serializedtablestring:find(char, searchstart, true)
    while charposition ~= nil do

      -- Bufferize code before character
      table.insert(buffer, serializedtablestring:sub(searchstart, charposition - 1))

      -- Ensure that we can replace this character, avoiding thoses in strings
      local ignoreposition, errormessage = mustbeignored(charposition)
      if errormessage then
        return nil, string.format('Unable to know if offset %d has to be formated.%s.', charposition, errormessage)
      elseif ignoreposition then
        -- Ignore character
        table.insert(buffer, char)
      else
        -- Actual character replacement
        table.insert(buffer, replacement)
      end

      -- Move to next replacement
      searchstart = charposition + 1
      charposition = serializedtablestring:find(char, searchstart, true)
    end

    -- Append remaining string
    table.insert(buffer, serializedtablestring:sub(searchstart))

    -- Replace original string
    serializedtablestring = table.concat(buffer)
  end

  -- Format resulting code
  return formatter.indentcode(serializedtablestring, '\n', true, '\t')
end
return M
