#!/usr/bin/python
## @file
# Firmware Configuration Editor (FCE) from https://firmware.intel.com/develop
# can parse BIOS image and generate Firmware Configuration file.
# This script bases on Firmware Configuration file, and generate the structure
# PCD setting in DEC/DSC/INF files.
#
# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#

'''
ConvertFceToStructurePcd
'''

import re
import os
import datetime
import argparse

#
# Globals for help information
#
__prog__        = 'ConvertFceToStructurePcd'
__version__     = '%s Version %s' % (__prog__, '0.1 ')
__copyright__   = 'Copyright (c) 2018, Intel Corporation. All rights reserved.'
__description__ = 'Generate Structure PCD in DEC/DSC/INF based on Firmware Configuration.\n'


dscstatement='''[Defines]
  VPD_TOOL_GUID                  = 8C3D856A-9BE6-468E-850A-24F7A8D38E08

[SkuIds]
  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.

[DefaultStores]
  0|STANDARD             # UEFI Standard default  0|STANDARD is reserved.
  1|MANUFACTURING        # UEFI Manufacturing default 1|MANUFACTURING is reserved.

[PcdsDynamicExVpd.common.DEFAULT]
  gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer|*
'''

decstatement = '''[Guids]
  gStructPcdTokenSpaceGuid = {0x3f1406f4, 0x2b, 0x487a, {0x8b, 0x69, 0x74, 0x29, 0x1b, 0x36, 0x16, 0xf4}}

[PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic,PcdsDynamicEx]
'''

infstatement = '''[Pcd]
'''

SECTION='PcdsDynamicHii'
PCD_NAME='gStructPcdTokenSpaceGuid.Pcd'

WARNING=[]
ERRORMSG=[]

class parser_lst(object):

  def __init__(self,filelist):
    self._ignore=['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64']
    self.file=filelist
    self.text=self.megre_lst()[0]
    self.content=self.megre_lst()[1]

  def megre_lst(self):
    alltext=''
    content={}
    for file in self.file:
      with open(file,'r') as f:
        read =f.read()
      alltext += read
      content[file]=read
    return alltext,content

  def struct_lst(self):#{struct:lst file}
    structs_file={}
    name_format = re.compile(r'(?<!typedef)\s+struct (\w+) {.*?;', re.S)
    for i in list(self.content.keys()):
      structs= name_format.findall(self.content[i])
      if structs:
        for j in structs:
          if j not in self._ignore:
            structs_file[j]=i
      else:
        print("%s"%structs)
    return structs_file

  def struct(self):#struct:{offset:name}
    unit_num = re.compile('(\d+)')
    offset1_re = re.compile('(\d+)\[')
    pcdname_num_re = re.compile('\w+\[(\S+)\]')
    pcdname_re = re.compile('\](.*)\<')
    pcdname2_re = re.compile('(\w+)\[')
    uint_re = re.compile('\<(\S+)\>')
    name_format = re.compile(r'(?<!typedef)\s+struct (\w+) {.*?;', re.S)
    name=name_format.findall(self.text)
    info={}
    unparse=[]
    if name:
      tmp_n = [n for n in name if n not in self._ignore]
      name = list(set(tmp_n))
      name.sort(key = tmp_n.index)
      name.reverse()
      #name=list(set(name).difference(set(self._ignore)))
      for struct in name:
        s_re = re.compile(r'struct %s :(.*?)};'% struct, re.S)
        content = s_re.search(self.text)
        if content:
          tmp_dict = {}
          text = content.group().split('+')
          for line in text[1:]:
            offset = offset1_re.findall(line)
            t_name = pcdname_re.findall(line)
            uint = uint_re.findall(line)
            if offset and uint:
              offset = offset[0]
              uint = uint[0]
              if t_name:
                t_name = t_name[0].strip()
                if (' ' in t_name) or ("=" in t_name) or (";" in t_name) or("\\" in name) or (t_name ==''):
                  WARNING.append("Warning:Invalid Pcd name '%s' for Offset %s in struct %s" % (t_name,offset, struct))
                else:
                  if '[' in t_name:
                    if uint in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
                      offset = int(offset, 10)
                      tmp_name = pcdname2_re.findall(t_name)[0] + '[0]'
                      tmp_dict[offset] = tmp_name
                      pcdname_num = int(pcdname_num_re.findall(t_name)[0],10)
                      uint = int(unit_num.findall(uint)[0],10)
                      bit = uint // 8
                      for i in range(1, pcdname_num):
                        offset += bit
                        tmp_name = pcdname2_re.findall(t_name)[0] + '[%s]' % i
                        tmp_dict[offset] = tmp_name
                    else:
                      tmp_name = pcdname2_re.findall(t_name)[0]
                      pcdname_num = pcdname_num_re.findall(t_name)[0]
                      line = [offset,tmp_name,pcdname_num,uint]
                      line.append(struct)
                      unparse.append(line)
                  else:
                    if uint not in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
                      line = [offset, t_name, 0, uint]
                      line.append(struct)
                      unparse.append(line)
                    else:
                      offset = int(offset,10)
                      tmp_dict[offset] = t_name
        info[struct] = tmp_dict
      if len(unparse) != 0:
        for u in unparse:
          if u[3] in list(info.keys()):
            unpar = self.nameISstruct(u,info[u[3]])
            info[u[4]]= dict(list(info[u[4]].items())+list(unpar[u[4]].items()))
    else:
      print("ERROR: No struct name found in %s" % self.file)
      ERRORMSG.append("ERROR: No struct name found in %s" % self.file)
    return info


  def nameISstruct(self,line,key_dict):
    dict={}
    dict2={}
    s_re = re.compile(r'struct %s :(.*?)};' % line[3], re.S)
    size_re = re.compile(r'mTotalSize \[(\S+)\]')
    content = s_re.search(self.text)
    if content:
      s_size = size_re.findall(content.group())[0]
    else:
      s_size = '0'
      print("ERROR: Struct %s not define mTotalSize in lst file" %line[3])
      ERRORMSG.append("ERROR: Struct %s not define mTotalSize in lst file" %line[3])
    size = int(line[0], 10)
    if line[2] != 0:
      for j in range(0, int(line[2], 10)):
        for k in list(key_dict.keys()):
          offset = size  + k
          name ='%s.%s' %((line[1]+'[%s]'%j),key_dict[k])
          dict[offset] = name
        size = int(s_size,16)+size
    elif line[2] == 0:
      for k in list(key_dict.keys()):
        offset = size + k
        name = '%s.%s' % (line[1], key_dict[k])
        dict[offset] = name
    dict2[line[4]] = dict
    return dict2

  def efivarstore_parser(self):
    efivarstore_format = re.compile(r'efivarstore.*?;', re.S)
    struct_re = re.compile(r'efivarstore(.*?),',re.S)
    name_re = re.compile(r'name=(\w+)')
    efivarstore_dict={}
    efitxt = efivarstore_format.findall(self.text)
    for i in efitxt:
      struct = struct_re.findall(i.replace(' ',''))
      name = name_re.findall(i.replace(' ',''))
      if struct and name:
        efivarstore_dict[name[0]]=struct[0]
      else:
        print("ERROR: Can't find Struct or name in lst file, please check have this format:efivarstore XXXX, name=xxxx")
        ERRORMSG.append("ERROR: Can't find Struct or name in lst file, please check have this format:efivarstore XXXX, name=xxxx")
    return efivarstore_dict

class Config(object):

  def __init__(self,Config):
    self.config=Config

  #Parser .config file,return list[offset,name,guid,value,help]
  def config_parser(self):
    ids_re =re.compile('_ID:(\d+)',re.S)
    id_re= re.compile('\s+')
    info = []
    info_dict={}
    with open(self.config, 'r') as text:
      read = text.read()
    if 'DEFAULT_ID:' in read:
      all_txt = read.split('FCEKEY DEFAULT')
      for i in all_txt[1:]:
        part = [] #save all infomation for DEFAULT_ID
        str_id=''
        ids = ids_re.findall(i.replace(' ',''))
        for m in ids:
          str_id +=m+'_'
        str_id=str_id[:-1]
        part.append(ids)
        section = i.split('\nQ') #split with '\nQ ' to get every block
        part +=self.section_parser(section)
        info_dict[str_id] = self.section_parser(section)
        info.append(part)
    else:
      part = []
      id=('0','0')
      str_id='0_0'
      part.append(id)
      section = read.split('\nQ')
      part +=self.section_parser(section)
      info_dict[str_id] = self.section_parser(section)
      info.append(part)
    return info_dict

  def eval_id(self,id):
    id = id.split("_")
    default_id=id[0:len(id)//2]
    platform_id=id[len(id)//2:]
    text=''
    for i in range(len(default_id)):
      text +="%s.common.%s.%s,"%(SECTION,self.id_name(platform_id[i],'PLATFORM'),self.id_name(default_id[i],'DEFAULT'))
    return '\n[%s]\n'%text[:-1]

  def id_name(self,ID, flag):
    platform_dict = {'0': 'DEFAULT'}
    default_dict = {'0': 'STANDARD', '1': 'MANUFACTURING'}
    if flag == "PLATFORM":
      try:
        value = platform_dict[ID]
      except KeyError:
        value = 'SKUID%s' % ID
    elif flag == 'DEFAULT':
      try:
        value = default_dict[ID]
      except KeyError:
        value = 'DEFAULTID%s' % ID
    else:
      value = None
    return value

  def section_parser(self,section):
    offset_re = re.compile(r'offset=(\w+)')
    name_re = re.compile(r'name=(\S+)')
    guid_re = re.compile(r'guid=(\S+)')
  #  help_re = re.compile(r'help = (.*)')
    attribute_re=re.compile(r'attribute=(\w+)')
    value_re = re.compile(r'(//.*)')
    part = []
    for x in section[1:]:
        line=x.split('\n')[0]
        line=value_re.sub('',line) #delete \\... in "Q...." line
        list1=line.split(' ')
        value=self.value_parser(list1)
        offset = offset_re.findall(x.replace(' ',''))
        name = name_re.findall(x.replace(' ',''))
        guid = guid_re.findall(x.replace(' ',''))
        attribute =attribute_re.findall(x.replace(' ',''))
        if offset and name and guid and value and attribute:
          if attribute[0] in ['0x3','0x7']:
            offset = int(offset[0], 16)
            #help = help_re.findall(x)
            text = offset, name[0], guid[0], value, attribute[0]
            part.append(text)
    return(part)

  def value_parser(self, list1):
    list1 = [t for t in list1 if t != '']  # remove '' form list
    first_num = int(list1[0], 16)
    if list1[first_num + 1] == 'STRING':  # parser STRING
      if list1[-1] == '""':
        value = "{0x0, 0x0}"
      else:
        value = 'L%s' % list1[-1]
    elif list1[first_num + 1] == 'ORDERED_LIST':  # parser ORDERED_LIST
      value_total = int(list1[first_num + 2])
      list2 = list1[-value_total:]
      tmp = []
      line = ''
      for i in list2:
        if len(i) % 2 == 0 and len(i) != 2:
          for m in range(0, len(i) // 2):
            tmp.append('0x%02x' % (int('0x%s' % i, 16) >> m * 8 & 0xff))
        else:
          tmp.append('0x%s' % i)
      for i in tmp:
        line += '%s,' % i
      value = '{%s}' % line[:-1]
    else:
      value = "0x%01x" % int(list1[-1], 16)
    return value


#parser Guid file, get guid name form guid value
class GUID(object):

  def __init__(self,path):
    self.path = path
    self.guidfile = self.gfile()
    self.guiddict = self.guid_dict()

  def gfile(self):
    for root, dir, file in os.walk(self.path, topdown=True, followlinks=False):
      if 'FV' in dir:
        gfile = os.path.join(root,'Fv','Guid.xref')
        if os.path.isfile(gfile):
          return gfile
        else:
          print("ERROR: Guid.xref file not found")
          ERRORMSG.append("ERROR: Guid.xref file not found")
          exit()

  def guid_dict(self):
    guiddict={}
    with open(self.guidfile,'r') as file:
      lines = file.readlines()
    guidinfo=lines
    for line in guidinfo:
      list=line.strip().split(' ')
      if list:
        if len(list)>1:
          guiddict[list[0].upper()]=list[1]
        elif list[0] != ''and len(list)==1:
          print("Error: line %s can't be parser in %s"%(line.strip(),self.guidfile))
          ERRORMSG.append("Error: line %s can't be parser in %s"%(line.strip(),self.guidfile))
      else:
        print("ERROR: No data in %s" %self.guidfile)
        ERRORMSG.append("ERROR: No data in %s" %self.guidfile)
    return guiddict

  def guid_parser(self,guid):
    if guid.upper() in self.guiddict:
      return self.guiddict[guid.upper()]
    else:
      print("ERROR: GUID %s not found in file %s"%(guid, self.guidfile))
      ERRORMSG.append("ERROR: GUID %s not found in file %s"%(guid, self.guidfile))
      return guid

class PATH(object):

  def __init__(self,path):
    self.path=path
    self.rootdir=self.get_root_dir()
    self.usefuldir=[]
    self.lstinf = {}
    for path in self.rootdir:
      for o_root, o_dir, o_file in os.walk(os.path.join(path, "OUTPUT"), topdown=True, followlinks=False):
        for INF in o_file:
          if os.path.splitext(INF)[1] == '.inf':
            for l_root, l_dir, l_file in os.walk(os.path.join(path, "DEBUG"), topdown=True,
                               followlinks=False):
              for LST in l_file:
                if os.path.splitext(LST)[1] == '.lst':
                  self.lstinf[os.path.join(l_root, LST)] = os.path.join(o_root, INF)
                  self.usefuldir.append(path)

  def get_root_dir(self):
    rootdir=[]
    for root,dir,file in os.walk(self.path,topdown=True,followlinks=False):
      if "OUTPUT" in root:
        updir=root.split("OUTPUT",1)[0]
        rootdir.append(updir)
    rootdir=list(set(rootdir))
    return rootdir

  def lst_inf(self):
    return self.lstinf

  def package(self):
    package={}
    package_re=re.compile(r'Packages\.\w+]\n(.*)',re.S)
    for i in list(self.lstinf.values()):
      with open(i,'r') as inf:
        read=inf.read()
      section=read.split('[')
      for j in section:
        p=package_re.findall(j)
        if p:
          package[i]=p[0].rstrip()
    return package

  def header(self,struct):
    header={}
    head_re = re.compile('typedef.*} %s;[\n]+(.*?)(?:typedef|formset)'%struct,re.M|re.S)
    head_re2 = re.compile(r'#line[\s\d]+"(\S+h)"')
    for i in list(self.lstinf.keys()):
      with open(i,'r') as lst:
        read = lst.read()
      h = head_re.findall(read)
      if h:
        head=head_re2.findall(h[0])
        if head:
          format = head[0].replace('\\\\','/').replace('\\','/')
          name =format.split('/')[-1]
          head = self.makefile(name).replace('\\','/')
          header[struct] = head
    return header

  def makefile(self,filename):
    re_format = re.compile(r'DEBUG_DIR.*(?:\S+Pkg)\\(.*\\%s)'%filename)
    for i in self.usefuldir:
      with open(os.path.join(i,'Makefile'),'r') as make:
        read = make.read()
      dir = re_format.findall(read)
      if dir:
        return dir[0]

class mainprocess(object):

  def __init__(self,InputPath,Config,OutputPath):
    self.init = 0xFCD00000
    self.inputpath = os.path.abspath(InputPath)
    self.outputpath = os.path.abspath(OutputPath)
    self.LST = PATH(self.inputpath)
    self.lst_dict = self.LST.lst_inf()
    self.Config = Config
    self.attribute_dict = {'0x3': 'NV, BS', '0x7': 'NV, BS, RT'}
    self.guid = GUID(self.inputpath)
    self.header={}

  def main(self):
    conf=Config(self.Config)
    config_dict=conf.config_parser() #get {'0_0':[offset,name,guid,value,attribute]...,'1_0':....}
    lst=parser_lst(list(self.lst_dict.keys()))
    efi_dict=lst.efivarstore_parser() #get {name:struct} form lst file
    keys=sorted(config_dict.keys())
    all_struct=lst.struct()
    stru_lst=lst.struct_lst()
    title_list=[]
    info_list=[]
    header_list=[]
    inf_list =[]
    for i in stru_lst:
      tmp = self.LST.header(i)
      self.header.update(tmp)
    for id_key in keys:
      tmp_id=[id_key] #['0_0',[(struct,[name...]),(struct,[name...])]]
      tmp_info={} #{name:struct}
      for section in config_dict[id_key]:
        c_offset,c_name,c_guid,c_value,c_attribute = section
        if c_name in efi_dict:
          struct = efi_dict[c_name]
          title='%s%s|L"%s"|%s|0x00||%s\n'%(PCD_NAME,c_name,c_name,self.guid.guid_parser(c_guid),self.attribute_dict[c_attribute])
          if struct in all_struct:
            lstfile = stru_lst[struct]
            struct_dict=all_struct[struct]
            try:
              title2 = '%s%s|{0}|%s|0xFCD00000{\n <HeaderFiles>\n  %s\n <Packages>\n%s\n}\n' % (PCD_NAME, c_name, struct, self.header[struct], self.LST.package()[self.lst_dict[lstfile]])
            except KeyError:
              WARNING.append("Warning: No <HeaderFiles> for struct %s"%struct)
              title2 = '%s%s|{0}|%s|0xFCD00000{\n <HeaderFiles>\n  %s\n <Packages>\n%s\n}\n' % (PCD_NAME, c_name, struct, '', self.LST.package()[self.lst_dict[lstfile]])
            header_list.append(title2)
          else:
            struct_dict ={}
            print("ERROR: Struct %s can't found in lst file" %struct)
            ERRORMSG.append("ERROR: Struct %s can't found in lst file" %struct)
          if c_offset in struct_dict:
            offset_name=struct_dict[c_offset]
            info = "%s%s.%s|%s\n"%(PCD_NAME,c_name,offset_name,c_value)
            inf = "%s%s\n"%(PCD_NAME,c_name)
            inf_list.append(inf)
            tmp_info[info]=title
          else:
            print("ERROR: Can't find offset %s with struct name %s"%(c_offset,struct))
            ERRORMSG.append("ERROR: Can't find offset %s with name %s"%(c_offset,struct))
        else:
          print("ERROR: Can't find name %s in lst file"%(c_name))
          ERRORMSG.append("ERROR: Can't find name %s in lst file"%(c_name))
      tmp_id.append(list(self.reverse_dict(tmp_info).items()))
      id,tmp_title_list,tmp_info_list = self.read_list(tmp_id)
      title_list +=tmp_title_list
      info_list.append(tmp_info_list)
    inf_list = self.del_repeat(inf_list)
    header_list = self.plus(self.del_repeat(header_list))
    title_all=list(set(title_list))
    info_list = self.remove_bracket(self.del_repeat(info_list))
    for i in range(len(info_list)-1,-1,-1):
      if len(info_list[i]) == 0:
        info_list.remove(info_list[i])
    for i in (inf_list, title_all, header_list):
      i.sort()
    return keys,title_all,info_list,header_list,inf_list

  def remove_bracket(self,List):
    for i in List:
      for j in i:
        tmp = j.split("|")
        if (('L"' in j) and ("[" in j)) or (tmp[1].strip() == '{0x0, 0x0}'):
          tmp[0] = tmp[0][:tmp[0].index('[')]
          List[List.index(i)][i.index(j)] = "|".join(tmp)
        else:
          List[List.index(i)][i.index(j)] = j
    for i in List:
      if type(i) == type([0,0]):
        i.sort()
    return List

  def write_all(self):
    title_flag=1
    info_flag=1
    if not os.path.isdir(self.outputpath):
      os.makedirs(self.outputpath)
    decwrite = write2file(os.path.join(self.outputpath,'StructurePcd.dec'))
    dscwrite = write2file(os.path.join(self.outputpath,'StructurePcd.dsc'))
    infwrite = write2file(os.path.join(self.outputpath, 'StructurePcd.inf'))
    conf = Config(self.Config)
    ids,title,info,header,inf=self.main()
    decwrite.add2file(decstatement)
    decwrite.add2file(header)
    infwrite.add2file(infstatement)
    infwrite.add2file(inf)
    dscwrite.add2file(dscstatement)
    for id in ids:
      dscwrite.add2file(conf.eval_id(id))
      if title_flag:
        dscwrite.add2file(title)
        title_flag=0
      if len(info) == 1:
        dscwrite.add2file(info)
      elif len(info) == 2:
        if info_flag:
          dscwrite.add2file(info[0])
          info_flag =0
        else:
          dscwrite.add2file(info[1])

  def del_repeat(self,List):
    if len(List) == 1 or len(List) == 0:
      return List
    else:
      if type(List[0]) != type('xxx'):
        alist=[]
        for i in range(len(List)):
          if i == 0:
            alist.append(List[0])
          else:
            plist = []
            for j in range(i):
              plist += List[j]
            alist.append(self.__del(list(set(plist)), List[i]))
        return alist
      else:
        return list(set(List))


  def __del(self,list1,list2):
    return list(set(list2).difference(set(list1)))

  def reverse_dict(self,dict):
    data={}
    for i in list(dict.items()):
      if i[1] not in list(data.keys()):
        data[i[1]]=[i[0]]
      else:
        data[i[1]].append(i[0])
    return data

  def read_list(self,list):
    title_list=[]
    info_list=[]
    for i in list[1]:
      title_list.append(i[0])
      for j in i[1]:
        info_list.append(j)
    return list[0],title_list,info_list

  def plus(self,list):
    nums=[]
    for i in list:
      if type(i) != type([0]):
        self.init += 1
        num = "0x%01x" % self.init
        j=i.replace('0xFCD00000',num.upper())
        nums.append(j)
    return nums

class write2file(object):

  def __init__(self,Output):
    self.output=Output
    self.text=''
    if os.path.exists(self.output):
      os.remove(self.output)

  def add2file(self,content):
    self.text = ''
    with open(self.output,'a+') as file:
      file.write(self.__gen(content))

  def __gen(self,content):
    if type(content) == type(''):
      return content
    elif type(content) == type([0,0])or type(content) == type((0,0)):
      return self.__readlist(content)
    elif type(content) == type({0:0}):
      return self.__readdict(content)

  def __readlist(self,list):
    for i in list:
      if type(i) == type([0,0])or type(i) == type((0,0)):
        self.__readlist(i)
      elif type(i) == type('') :
        self.text +=i
    return self.text

  def __readdict(self,dict):
    content=list(dict.items())
    return self.__readlist(content)

def stamp():
  return datetime.datetime.now()

def dtime(start,end,id=None):
  if id:
    pass
    print("%s time:%s" % (id,str(end - start)))
  else:
    print("Total time:%s" %str(end-start)[:-7])


def main():
  start = stamp()
  parser = argparse.ArgumentParser(prog = __prog__,
                                   description = __description__ + __copyright__,
                                   conflict_handler = 'resolve')
  parser.add_argument('-v', '--version', action = 'version',version = __version__, help="show program's version number and exit")
  parser.add_argument('-p', '--path', metavar='PATH', dest='path', help="platform build output directory")
  parser.add_argument('-c', '--config',metavar='FILENAME', dest='config', help="firmware configuration file")
  parser.add_argument('-o', '--outputdir', metavar='PATH', dest='output', help="output directoy")
  options = parser.parse_args()
  if options.config:
    if options.path:
      if options.output:
        run = mainprocess(options.path, options.config, options.output)
        print("Running...")
        run.write_all()
        if WARNING:
          warning = list(set(WARNING))
          for j in warning:
            print(j)
        if ERRORMSG:
          ERROR = list(set(ERRORMSG))
          with open("ERROR.log", 'w+') as error:
            for i in ERROR:
              error.write(i + '\n')
          print("Some error find, error log in ERROR.log")
        print('Finished, Output files in directory %s'%os.path.abspath(options.output))
      else:
        print('Error command, no output path, use -h for help')
    else:
      print('Error command, no build path input, use -h for help')
  else:
    print('Error command, no output file, use -h for help')
  end = stamp()
  dtime(start, end)

if __name__ == '__main__':
  main()
