import sys
import json
import re
import os
import hashlib
import time
import subprocess

from file_util import FileUtil

INCLUDE_DIRECTORY = './include'
ASSETS_INCLUDE = INCLUDE_DIRECTORY + '/asset_sections.h'

class GenerateAssets:
    def __init__(self, rootDir, version):
        self.ASSETS_ASM_DIR = rootDir + '/asm/assets'
        self.ASSETS_FILENAME = self.ASSETS_ASM_DIR + '/assets.s'
        self.ASSETS_DIR = rootDir + '/assets'
        self.UCODE_DIR = rootDir + '/ucode/' + version
        self.UCODE_TEXT_FILENAME = self.ASSETS_ASM_DIR + '/ucode_text.s'
        self.UCODE_DATA_FILENAME = self.ASSETS_ASM_DIR + '/ucode_data.s'
        self.BUILD_DIR = rootDir + '/build'
        self.VERSION = version
        
        self.generate_assets_file()
        self.generate_ucode_files()

    def generate_assets_file(self):
        with open(self.ASSETS_DIR + "/" + self.VERSION + '/ignoreMe.txt', 'w') as a_file:
            a_file.write("This file is automatically generated by generate_assets.py, and is used to check if the assets have been updated.")
        args = ["tools/dkr_assets_tool", "-i", self.VERSION, self.ASSETS_DIR, INCLUDE_DIRECTORY, self.BUILD_DIR, self.ASSETS_ASM_DIR]
        createAssets = subprocess.Popen(args, stdout=subprocess.PIPE)
        createAssets.wait()
        streamdata = createAssets.communicate()[0]
        if createAssets.returncode != 0:
            raise SystemExit("An error occured while generating /asm/assets files. Error code " + str(createAssets.returncode) + ". Aborting!")
        with open(self.ASSETS_DIR + '/' + self.VERSION + '/assets.json') as jsonFile:
            assetsJSON = json.load(jsonFile)
            self.numAssets = len(assetsJSON['assets']['order'])

    # Note: I am assuming that the order of microcodes did not change between versions.
    # TODO: Will probably need to refactor this later.
    def generate_ucode_files(self):
        assetsUCodeText = '# This file was generated by generate_ld.py\n\n'
        assetsUCodeText += '.include "macros.inc"\n\n'
        assetsUCodeText += self.generate_ucode_file('rspUnknownStart', 'ucode/ucode_unknown.bin')
        assetsUCodeText += self.generate_ucode_file('rspF3DDKRBootStart', 'ucode/ucode_boot.bin')
        assetsUCodeText += self.generate_ucode_file('rspF3DDKRDramStart', 'ucode/ucode_f3ddkr_dram.bin')
        assetsUCodeText += self.generate_ucode_file('rspF3DDKRFifoStart', 'ucode/ucode_f3ddkr_fifo.bin')
        assetsUCodeText += self.generate_ucode_file('rspF3DDKRXbusStart', 'ucode/ucode_f3ddkr_xbus.bin')
        assetsUCodeText += self.generate_ucode_file('rspUnknown2Start', 'ucode/ucode_unknown_2.bin')
        with open(self.UCODE_TEXT_FILENAME, "w") as assetsFile:
            assetsFile.write(assetsUCodeText)
        
        assetsUCodeData = '# This file was generated by generate_ld.py\n\n'
        assetsUCodeData += '.include "macros.inc"\n\n'
        assetsUCodeData += self.generate_ucode_file('rspUnknownDataStart', 'ucode/data_unknown.bin')
        assetsUCodeData += self.generate_ucode_file('rspF3DDKRDataDramStart', 'ucode/data_f3ddkr_dram.bin')
        assetsUCodeData += self.generate_ucode_file('rspF3DDKRDataFifoStart', 'ucode/data_f3ddkr_fifo.bin')
        assetsUCodeData += self.generate_ucode_file('rspF3DDKRDataXbusStart', 'ucode/data_f3ddkr_xbus.bin')
        assetsUCodeData += self.generate_ucode_file('rspUnknown2DataStart', 'ucode/data_unknown_2.bin')
        
        with open(self.UCODE_DATA_FILENAME, "w") as assetsFile:
            assetsFile.write(assetsUCodeData)
            
    def generate_ucode_file(self, label, path):
        return 'glabel ' + label + '\n.incbin "' + self.BUILD_DIR + '/' + self.VERSION + '/' + path + '"\n'
