local stdnse = require "stdnse"
local table = require "table"
_ENV = stdnse.module("listop", stdnse.seeall)
--[[
Functional programming style 'list' operations
    bool  is_empty(list)
    bool  is_list(value)
    value apply(function, list)
    list  map(function, list)
    list  filter(function, list)
    list  flatten(list)
    list  append(list1, list2)
    list  cons(value1, value2)
    list  reverse(list)
    value car(list)
    value ncar(list, x)
    list  cdr(list)
    list  ncdr(list, x)
    where 'list' is an indexed table
    where 'value' is an lua datatype
--]]
function is_empty(l)
  return #l == 0 and true or false;
end
function is_list(l)
  return type(l) == 'table' and true or false;
end
function map(f, l)
  local results = {}
  for _, v in ipairs(l) do
    results[#results+1] = f(v);
  end
  return results;
end
function apply(f, l)
  return f(table.unpack(l))
end
function filter(f, l)
  local results = {}
  for i, v in ipairs(l) do
    if(f(v)) then
      results[#results+1] = v;
    end
  end
  return results
end
function car(l)
  return l[1]
end
function cdr(l)
  return {table.unpack(l, 2)}
end
function ncar(l, x)
  return l[x or 1];
end
function ncdr(l, x)
  return {table.unpack(l, x or 2)};
end
function cons(v1, v2)
  return{ is_list(v1) and {table.unpack(v1)} or v1, is_list(v2) and {table.unpack(v2)} or v2}
end
function append(l1, l2)
  local results = {table.unpack(l1)}
  for _, v in ipairs(l2) do
    results[#results+1] = v;
  end
  return results
end
function reverse(l)
  local results = {}
  for i=#l, 1, -1 do
    results[#results+1] = l[i];
  end
  return results
end
function flatten(l)
  local function flat(r, t)
    for i, v in ipairs(t) do
      if(type(v) == 'table') then
        flat(r, v)
      else
        table.insert(r, v)
      end
    end
    return r
  end
  return flat({}, l)
end
return _ENV;
