--  ========================================================================
--
--  FILE: boot.lua
--
--  SERVICES: Boot up initialization
--
--  ========================================================================
--  ========================================================================
--
--               Copyright  1999-2006 QUALCOMM Incorporated
--                     All Rights Reserved.
--                   QUALCOMM Proprietary/GTDR
--
--  ========================================================================
--  ========================================================================

-- Import Section:
loadlib("lfile")
loadlib("lsys")
loadlib("lutil")

local  SUCCESS = 0 -- No error
local  EFAILED = 1 -- General failure
local  EITEMBUSY = 32


local level = 1

local first_run_executed = false

--====================================================================

-- Constant list of files
local CONST_script_files = {}
		  					
local datastore_compiled = false

local enable_debug = true


local function populate_script_files_table(zipArchive)

	-- iterate over an archive and uncompress the unpack script.
	for archivedFile in zip.enum(zipArchive) do
	   
		CONST_script_files[archivedFile] = true
	   
	end

end

--====================================================================

local function check_files(script_files, dirName)

	local missing_script = false
	local missing_script_name = ""



    if enable_debug then

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d - check_files in %s", info.short_src, info.currentline, dirName) )

        -- print ( string.format("[%s]:%d - traceback: %s", info.short_src, info.currentline, debug.traceback()) )

	end

	-- enumerate over all of the files in dirName
	for k, v in pairs(script_files) do

		if enable_debug then
		
			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d - CHECK_FILES: FILE %s",info.short_src, info.currentline, dirName..k) )
		
		end
		
		if not file.test(dirName..k) then

			missing_script = true
			
			missing_script_name = dirName..k

			break

		end
		
	end

	if missing_script then
	
	    if enable_debug then	    

			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d CHECK_FILES: ERROR FAILED MISSING %s",info.short_src, info.currentline, missing_script_name) )

		end

		return false, "MESSAGE"

	end

	return true
end

--====================================================================




--====================================================================

local function remove_files(script_files, dirPath)

    if enable_debug then

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d - DELETE FILES IN %s", info.short_src, info.currentline, dirPath) )

	end

	-- enumerate over all of the files in dirName
	for k, v in pairs(script_files) do


		if file.test(dirPath..k) then

			file.remove(dirPath..k)

			if enable_debug then

				local info = debug.getinfo(level, "Sl")
				print ( string.format("[%s]:%d - DELETE FILES: FILE %s",info.short_src, info.currentline, dirPath..k) )

			end

		end

	end

end

--====================================================================



local function first_run(script_files, sys_mdn)

	local init_zip = "init.zip"
	local init_script = "init.lua"


    first_run_executed = true

	
    if enable_debug then

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d FIRST_RUN: file.test(init_zip)",info.short_src, info.currentline) )
		
	end

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

	if not file.test(init_zip) then

	   local info = debug.getinfo(level, "Sl")
	   print ( string.format("[%s]:%d FIRST_RUN: ERROR NOT FOUND file.test(init_zip)",info.short_src, info.currentline) )

	   return false, "MESSAGE"

	end

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

    populate_script_files_table(init_zip)
    
	-------------------------------------------------------------


    if enable_debug then

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d FIRST_RUN: zip.uncompress(init_zip)",info.short_src, info.currentline) )

	end


	-- unzip the files to EFS

    remove_files(CONST_script_files, "fs:/~/")

    local zip_nerr = zip.uncompress(init_zip, "fs:/~/")

	if zip_nerr then

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d FIRST_RUN: ERROR UNZIP ",info.short_src, info.currentline) )

		return false, "MESSAGE"

	end

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

    local required_files_exist, required_files_msg = check_files(CONST_script_files, "fs:/~/")

	if not required_files_exist then

	    if enable_debug then
	
			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d FIRST_RUN: FAILED check_files after unzip",info.short_src, info.currentline) )
	
		end

		return false, "MESSAGE"

	end

    if enable_debug then

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d FIRST_RUN: SUCCESS check_files after unzip",info.short_src, info.currentline) )

	end

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

    if enable_debug then

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d  FIRST_RUN: compile init script",info.short_src, info.currentline) )

	end

	local pcall_err, return_value

	-- compile init script
	pcall_err, return_value = pcall(require,init_script)

    if ( pcall_err ) then
    
	    if enable_debug then

			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d FIRST_RUN: SUCCESS compile init script",info.short_src, info.currentline) )

		end    

		if not script_init.start() then

		    if enable_debug then
	
				local info = debug.getinfo(level, "Sl")
				print ( string.format("[%s]:%d FIRST_RUN: FAILED script_init.start()",info.short_src, info.currentline) )
	
			end    

			return false, "MESSAGE"

		end

    else
	
	    if enable_debug then
	
			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d FIRST_RUN: FAILED %s",info.short_src, info.currentline, return_value) )
	
		end
		
		return false, "MESSAGE"

    end

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

	if (datastore_compiled == false) then

	    if enable_debug then

			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d FIRST_RUN: compile datastore script",info.short_src, info.currentline) )
			
		end

		local pcall_err, exec_datastore

		-- compile datastore script
        pcall_err, return_value = pcall( require, "datastore.lua" )

	    if ( pcall_err ) then


		    if enable_debug then
	
				local info = debug.getinfo(level, "Sl")
				print ( string.format("[%s]:%d FIRST_RUN: SUCCESS compile datastore script",info.short_src, info.currentline) )
	
			end


			-- datastore = return_value

			datastore_compiled = true

	    else

		    if enable_debug then
	
				local info = debug.getinfo(level, "Sl")
				print ( string.format("[%s]:%d FIRST_RUN: FAILED compile datastore script",info.short_src, info.currentline) )

			end

	       return false, "MESSAGE"

	    end

	end
	-------------------------------------------------------------

	datastore.set_mdn ( sys_mdn )

	if ( sys_mdn ~= datastore.get_mdn() ) then

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d FIRST_RUN: ERROR ",info.short_src, info.currentline) )

		return false, "MESSAGE"

	end
	-------------------------------------------------------------

    if enable_debug then

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d FIRST_RUN: FINAL SUCCESS sysMDN %s - datastoreMDN %s",info.short_src, info.currentline,sys_mdn,datastore.get_mdn() ) )
		
	end

	return true -- SUCCESS

end


local function init()

	local init_zip = "init.zip"

	---------------- get device MDN -----------------------------

    if enable_debug then
    
		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d INIT: get device MDN",info.short_src, info.currentline) )

	end
	
	local sys_mdn, err_sys_mdn = sys.get_deviceinfo_string(AEE_DEVICEITEM_MDN)
	
	if err_sys_mdn then

	    if enable_debug then

			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d FATAL ERROR: sys MDN not available",info.short_src, info.currentline) )

		end

        return EFAILED 

    else

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d SUCCESS getting sys MDN",info.short_src, info.currentline) )

	end
    

	local info = debug.getinfo(level, "Sl")
	print ( string.format("[%s]:%d INIT: device MDN = %s",info.short_src, info.currentline, sys_mdn) )


    ------------------- check if .lua files exist ---------------

    if enable_debug then

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d INIT: check if .lua files exist",info.short_src, info.currentline) )

	end

    populate_script_files_table(init_zip)
    local required_files_exist, required_files_msg = check_files(CONST_script_files, "fs:/~/")

	if not required_files_exist then

		-- 1st run: unzipping the init.zip and executing init.lua
		
		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d INIT: Call First_Run",info.short_src, info.currentline) )

		local ret_code, ret_msg = first_run(CONST_script_files, sys_mdn)

		if not ret_code then

			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d INIT: ERROR ",info.short_src, info.currentline) )

			return EFAILED

		end

	else ----- check if datastore persistent files are consistent

	    if enable_debug then

			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d INIT: check if datastore persistent files are consistent",info.short_src, info.currentline) )

		end

		local pcall_err, exec_datastore

		-- compile datastore script
		
		pcall_err, return_value = pcall(require, "datastore.lua")
		
	    if ( pcall_err ) then

		    if enable_debug then
	
				local info = debug.getinfo(level, "Sl")
				print ( string.format("[%s]:%d INIT: SUCCESS pcall(require, \"datastore.lua\")",info.short_src, info.currentline) )
	
			end

			--datastore = return_value

			datastore_compiled = true

	    else

		    if enable_debug then
	
				local info = debug.getinfo(level, "Sl")
				print ( string.format("[%s]:%d INIT ERROR: - %s",info.short_src, info.currentline, return_value) )  -- FAILED pcall(require, datastore.lua)
	
			end
			
			return EFAILED

	    end


		pcall_err, pcall_readFromFS = pcall(datastore.readFromFS)

	    if ( pcall_err == false )  then

			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d ERROR: readFromFS %s",info.short_src, info.currentline,pcall_readFromFS) )

			return EFAILED

	    end

		if not pcall_readFromFS then

			-- 1st run: unzipping the init.zip and executing init.lua
			
			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d Call First RUN ",info.short_src, info.currentline) )

			local ret_code, ret_msg = first_run(CONST_script_files, sys_mdn)

			if not ret_code then

				local info = debug.getinfo(level, "Sl")
				print ( string.format("[%s]:%d INIT: ERROR ",info.short_src, info.currentline) )

				return EFAILED

			end

		end

	end

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

	if (datastore_compiled == false ) then
	
		-- compile datastore script

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d INIT: compile datastore",info.short_src, info.currentline) )
		
		pcall_err, exec_datastore = pcall(require, "datastore.lua")
		
	    if ( pcall_err ) then

			--exec_datastore()

			datastore_compiled = true

	    else

			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d INIT: ERROR ",info.short_src, info.currentline) )

			return EFAILED

	    end

	end

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

    if enable_debug then

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d INIT: get datastore_mdn",info.short_src, info.currentline) )

	end

	--datastore.init()
	
	local datastore_mdn = datastore.get_mdn() 
	
    if not datastore_mdn then
    	        	
		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d INIT: ERROR ",info.short_src, info.currentline) )

    	return EFAILED
    	
    end

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

    if enable_debug then

		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d INIT: CHECK sys_mdn[%s] and datastore_mdn[%s]",info.short_src, info.currentline, sys_mdn, datastore_mdn ) )

	end

	
	if (sys_mdn ~= datastore_mdn) then
	
		-- 1st run: unzipping the init.zip and executing init.lua

	    if enable_debug then

			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d call FIRST RUN - sys_mdn[%s] is DIFFERENT from datastore_mdn[%s]",info.short_src, info.currentline, sys_mdn, datastore_mdn ) )

		end

		
		local ret_code, ret_msg = first_run(CONST_script_files, sys_mdn)
		
		if not ret_code then

			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d INIT: ERROR ",info.short_src, info.currentline) )

			return EFAILED
		
		end
		
	else

	    if enable_debug then

			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d sys_mdn[%s] is EQUAL to datastore_mdn[%s]",info.short_src, info.currentline, sys_mdn, datastore_mdn ) )

		end

	end	
	
	-------------------------------------------------------------				

	if not first_run_executed then

		local pcall_err_1, pcall_result_1 = pcall(require, "fetch.lua")
		local pcall_err_2, pcall_result_2 = pcall(require, "interface.lua")
		
	    if pcall_err_1 and pcall_err_2 then

			local info = debug.getinfo(level, "Sl")
			print ( string.format("[%s]:%d INIT: calling fetch.lua/interface.lua",info.short_src, info.currentline) )

   			fetch_init()
			interfaceInit()

	    else

		    if ( type(pcall_result_1) == "string" ) then
				local info = debug.getinfo(1, "Sl")
				print ( string.format("[%s]:%d ERROR %s",info.short_src, info.currentline, pcall_result_1) )

			end

		    if ( type(pcall_result_2) == "string" ) then
				local info = debug.getinfo(1, "Sl")
				print ( string.format("[%s]:%d ERROR %s",info.short_src, info.currentline, pcall_result_2) )

			end

			return EFAILED

	    end

	end

	-------------------------------------------------------------
	
	return SUCCESS

end


--====================================================================

-- Export Section:
-- Declare everything this package needs to export to outside


--==============================================================================
-- This function is called by the dataActor to start boot procedure
-- This is a specific function between dataActor and boot script
--==============================================================================

function boot_init()


	local pcall_err, retvalue = pcall( init )

    if ( pcall_err ) then
	
		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d RETURN boot() : %d",info.short_src, info.currentline, retvalue) )

		return retvalue
				    
	else
		
		local info = debug.getinfo(level, "Sl")
		print ( string.format("[%s]:%d ERROR boot() - CAUSE: %s",info.short_src, info.currentline, retvalue) )
		
		return EFAILED

	end

end
	
