
-- TODO discriminate integer and numeric in checks of species, traits, ltypes...
-- TODO, proper error handleing?

-- TODO: remove all call to pairs() => causes random behaviour => ruins reproductibility
-- Files to check: init_allelic_effect.lua ltypeConfig.lua match.lua misc_func.lua outputs.lua speciesConfig.lua traitsConfig.lua userData.lua


-- Main lua file
-- Naming conventions :
--    variable => maj sep
--    functions underscore sep

--TEMP
--math.randomseed(os.tim
--S1 = math.random()*100
--S2 = math.random()*100



--math.randomseed(41)
S1 = 42
S2 = 44
verbose = false
--------------------------------------------------------------------------------
-------------------------- Path, modules and files loading ---------------------
--------------------------------------------------------------------------------

-- Paths definitions
local srcPath = "./luaSrc/"
local usrPath = "../user_input/"
local rDir = "./R/"

-- Loading others source files
dofile(srcPath .. "misc_func.lua")    -- Miscellaneous global functions

-- Require path
package.path = './luaSrc/?.lua;' .. package.path
--Require
stats = require("stats")
gradient = require("gradient")
conf = require("paramConfig")   -- config file checking module
spe = require("speciesConfig")
evt = require("eventConfig")
userData = require("userData")  -- User data reading module
initZopt = require("initZopt")
initE = require("initE")
match = require("match")
indiv = require("indivConfig")
out = require("outputs")

--------------------------------------------------------------------------------
----------------------- Loading user inputs files  -----------------------------
--------------------------------------------------------------------------------

print("\nStep 1: Loading all user's content...")

-- 1 -- Loading of configuration file & checking
-- Just get the globals from the file
local env = {} -- Restricted (empty) environement
local configFile = usrPath.."simuConf.lua"
local usrConfig = userData.load_file_globals(configFile, env)
local env2 = {} -- Restricted (empty) environement
local seedFile = usrPath.."seed.lua"
local usrSeed = userData.load_file_globals(seedFile, env2)
local env3 = {} -- Restricted (empty) environement
local envirFile = usrPath.."environment.lua"
local usrEnvir = userData.load_file_globals(envirFile, env3)

S1 = usrSeed.seed1init
S2 = usrSeed.seed2init
--print("init seed")
--print(S1)
--print(S2)
--print(usrSeed.seed2)

-- 2 -- Custom (optional) user data:
-- Zopt, E, SelInt, All_Eff, Individuals, Flux Matrix/Pattern
-- Everything not species, traits or conf is loaded here and stored by type
-- data_index.txt
local indexFile = ".struct/index.txt"
local dataFiles = userData.load_index_file(indexFile, usrPath)
local userDataFrames = userData.load_data(dataFiles)


-- 3 -- Loading of traits - No content check except id & type
local traitsIndex = ".struct/traits_index.txt"
local traitsFiles = userData.load_index_file(traitsIndex, usrPath)
local usrTraits = userData.load_traits(traitsFiles)



-- 4 -- species - No content check except id & type
local speciesIndex = ".struct/species_index.txt"
local speciesFiles = userData.load_index_file(speciesIndex, usrPath)
local usrSpecies = userData.load_species(speciesFiles)

print("User's content loaded.")





--------------------------------------------------------------------------------
--------------------------- Matching available data  ---------------------------
--------------------------------------------------------------------------------
print("\nStep 2: Matching user's content...")

-- Matching user Trait with user Data (Zopt, E, Sel_int, Allelic effects)
match.trait_data(usrTraits, userDataFrames)
--print("MATCH?"..type(usrTraits))

-- Matching species and user Data (flux matrix, flux pattern) by id
match.species_data(usrSpecies, userDataFrames)

-- Matching Species & traits by id (check field traits id)
match.species_traits(usrSpecies, usrTraits)

-- Loading individuals according to their species
local usrInds = match.individuals(userDataFrames, usrSpecies)
--for k, v in ipairs(usrInds) do print(k, v) end
local usrDemo = match.demo(userDataFrames, usrSpecies) -- TODO -- implement function

local usrAllFreq = nil

-- TODO -- Match other types (all frequences, demo...)

-- Now everything interesting is extracted from userDataFrames,
-- we can delete for clarity
userDataFrames = nil
--print("MATCH post void?"..type(usrTraits))

print("User's content matched.")


--------------------------------------------------------------------------------
------------------------- Checking & generating data ---------------------------
--------------------------------------------------------------------------------
print("\nStep 3: Checking user's content...")

-- Check missing fields in userconfig, config is GLOBAL
print("        Checking usrConfig")
config = conf.check(usrConfig)

print("        Checking usrSeed")
configSeed = conf.check_seedFile(usrSeed)

print("        Checking usrEnvir")
--configEnvir = conf.check_envirFile(usrEnvir)
eventsTable = evt.check_all(usrEnvir)

for key,value in pairs(eventsTable) do
        print(key,value.id)
end


local outDir = config.outputDir .. "settings/" --"../raw_outputs/general_infos/"
-- print("outdir:" .. outDir)

-- Check each field from species, traits & loctypes
-- TODO => if userdata is loaded, warn if generation parameters not used?
print("        Checking species and traits")
speciesTable = spe.check_all(usrSpecies, config)






-- Check populations
populations = indiv.make_multi(usrInds, usrDemo, usrAllFreq, config, speciesTable, rDir, outDir)


--[[
if (verbose) then
    print("User's content checked.")
    t="Lua gasdev: "
    for i = 1, 5 do
        t=t..gasdev()
    end
    print(t)
    t="Random Lua: "
    for i = 1, 5 do
        t=t..Random()
    end
    print(t)
    t="math.random Lua: "
    for i = 1, 5 do
        t=t..math.random()
    end
    print(t)
end--]]

--------------------------------------------------------------------------------
-------------------------------- Outputing  data -------------------------------
--------------------------------------------------------------------------------

-- Reset file -- TODO tempoprary solutions
local file = ""
file = assert(io.open(outDir.."fluxMat.txt", "w")); file:close()
file = assert(io.open(outDir.."allEff.txt", "w")); file:close()
file = assert(io.open(outDir.."e.txt", "w")); file:close()
file = assert(io.open(outDir.."individuals.txt", "w")); file:close()
file = assert(io.open(outDir.."demo.txt", "w")); file:close()
file = assert(io.open(outDir.."sel_int.txt", "w")); file:close()
file = assert(io.open(outDir.."zopt.txt", "w")); file:close()

file = assert(io.open(usrPath.."fluxMat.txt", "w")); file:close()
--file = assert(io.open(usrPath.."allEff.txt", "w")); file:close()
file = assert(io.open(usrPath.."e.txt", "w")); file:close()
file = assert(io.open(usrPath.."demo.txt", "w")); file:close()
file = assert(io.open(usrPath.."sel_int.txt", "w")); file:close()
file = assert(io.open(usrPath.."zopt.txt", "w")); file:close()

-- Print data
for _, spe in ipairs(speciesTable) do
    out.print_species(spe, outDir)
    out.refresh_matrix(spe, usrPath)
end

-- Print individuals
out.print_individuals(populations, outDir.."individuals.txt", "w")
