
# To have tab on html file generated
CVE_IMAGE_CONTENT_WITH_TAB ?= "1"

# Configure on BSP side this var if you expect the summary to be generated
ENABLE_IMAGE_CVE_SUMMARY ??= "0"

ST_CVE_SUMMARY_DIR ?= "${WORKDIR}/cve-summary/"
ST_CVE_SUMMARY_DEPLOYDIR ?= "${DEPLOY_DIR}/images/${MACHINE}"
ST_CVE_SUMMARY_NAME ?= "${IMAGE_NAME}-cve_content.html"
ST_CVE_SUMMARY_LINK_NAME ?= "${IMAGE_LINK_NAME}-cve_content.html"

ST_MAIN_COMPONENTS ?= ""

def cve_create_summary(d):
    import re
    import json
    tab =  d.expand("${CVE_IMAGE_CONTENT_WITH_TAB}")

    ref_image_name =  d.expand("${IMAGE_LINK_NAME}")
    deploy_image_dir = d.expand("${DEPLOY_DIR_IMAGE}")
    temp_deploy_image_dir = d.expand("${IMGDEPLOYDIR}")

    cve_deploy_dir = d.expand("${DEPLOY_DIR}/cve")

    cve_summary_deploydir = d.getVar('ST_CVE_SUMMARY_DIR')
    cve_summary_name = d.getVar('ST_CVE_SUMMARY_NAME')
    cve_summary_link = d.getVar('ST_CVE_SUMMARY_LINK_NAME')

    components_list = d.getVar('ST_MAIN_COMPONENTS')

    datetime = d.getVar('DATETIME')

    if tab.startswith("1"):
        with_tab = 1
    else:
        with_tab = None

    def private_open(filename):
        result = None
        if os.path.exists(filename):
            try:
                with open(filename, "r") as lic:
                    result = lic.readlines()
            except IOError:
                bb.warn("IMG LIC SUM: Cannot open file %s" % (filename))
                result = ""
            except:
                bb.warn("IMG LIC SUM: Error with file %s" % (filename))
                result = ""
        else:
            bb.warn("IMG LIC SUM: File does not exist with open file %s" % (filename))

            result = ""
        return result

    class HTMLSummaryfile():
        ''' format definition '''
        bold = "font-weight: bold; background-color: #cccccc;"
        red = "background-color: #ff0000;"
        center_format = "align: center;"
        border_format = "border: 1;"
        wrap_format = ""
        wrap_red_format = "background-color: #ff0000;"

        blue = "background-color: #0000ff;"
        green = "background-color: #00ff00;"

        opened_file = None

        def openfile(self, file_name):
            self.opened_file = open(file_name, 'w')
        def closefile(self):
            self.opened_file.close()
        def startTable(self, style=None, classes=None):
            if style:
                if classes:
                    self.opened_file.write("<TABLE STYLE='%s' class='%s'>\n" % (style, classes))
                else:
                    self.opened_file.write("<TABLE STYLE='%s'>\n" % style)
            else:
                if classes:
                    self.opened_file.write("<TABLE BORDER=1 class='%s'>\n" % classes)
                else:
                    self.opened_file.write("<TABLE border=1>\n")

        def stopTable(self):
            self.opened_file.write("</TABLE>\n")
        def startRow(self, style=None):
            self.opened_file.write("<TR>\n")
        def stopRow(self, style=None):
            self.opened_file.write("</TR>\n")
        def startColumn(self, style=None):
            if style:
                self.opened_file.write("<TD STYLE='%s'>\n")
            else:
                self.opened_file.write("<TD>\n")
        def stopColumn(self, style=None):
            self.opened_file.write("</TD>\n")
        def addColumnHeaderContent(self, content, style=None):
            if style:
                self.opened_file.write("<TH STYLE='%s'>%s</TH>\n" % (style, content))
            else:
                self.opened_file.write("<TH><B>%s</B></TH>\n" % content)
        def addColumnContent(self, content, style=None):
            if style:
                self.opened_file.write("<TD STYLE='%s'>%s</TD>\n" % (style, content))
            else:
                self.opened_file.write("<TD>%s</TD>\n" % content)
        def addColumnURLOUTContent(self, content, url, style=None):
            if style:
                self.opened_file.write("<TD STYLE='%s'><A HREF='%s' TARGET='_blank'>%s</A></TD>\n" % (style, url, content))
            else:
                self.opened_file.write("<TD><A HREF='%s' TARGET='_blank'>%s</A></TD>\n" % (url, content))
        def addColumnEmptyContent(self, style=None):
            if style:
                self.opened_file.write("<TD STYLE='%s'><BR/></TD>\n" % style)
            else:
                self.opened_file.write("<TD><BR/></TD>\n")
        def addNewLine(self):
            self.opened_file.write("<BR/>\n")
        def addContent(self, content):
            self.opened_file.write(content)
        def addURLContent(self, content, url):
            self.opened_file.write("<A HREF='%s'>%s</A>\n" %(url, content))
        def startBlock(self):
            self.opened_file.write("<UL>\n")
        def stopBlock(self):
            self.opened_file.write("</UL>\n")
        def addTitle(self, title):
            self.opened_file.write("<H1>{}</H1>\n".format(title))

        def addAnchor(self, anchor):
            self.opened_file.write("<A name='%s'/>\n" % anchor)
        def startDiv(self, anchor, title, style=None):
            self.opened_file.write("<div id='%s' class='tabcontent'>\n" % anchor)
            self.opened_file.write("<H1>%s</H1>\n" % title)

        def stopDiv(self):
            self.opened_file.write("</div>\n")

        def beginHtml(self):
            self.opened_file.write("<HTML>\n")
            self.opened_file.write('<HEAD>\n')
            self.opened_file.write("   <STYLE TYPE='text/css'>\n")
            self.opened_file.write("/* Style the tab buttons */\n")
            self.opened_file.write(".tablink {\n")
            self.opened_file.write("    background-color: #555;\n")
            self.opened_file.write("    color: white;\n")
            self.opened_file.write("    float: left;\n")
            self.opened_file.write("    border: none;\n")
            self.opened_file.write("    outline: none;\n")
            self.opened_file.write("    cursor: pointer;\n")
            self.opened_file.write("    padding: 14px 16px;\n")
            self.opened_file.write("    font-size: 17px;\n")
            self.opened_file.write("    width: 25%;\n")
            self.opened_file.write("}\n")
            self.opened_file.write("\n")
            self.opened_file.write("/* Change background color of buttons on hover */\n")
            self.opened_file.write(".tablink:hover {\n")
            self.opened_file.write("    background-color: #777;\n")
            self.opened_file.write("}\n")
            self.opened_file.write("\n")
            self.opened_file.write("/* Set default styles for tab content */\n")
            self.opened_file.write(".tabcontent {\n")
            self.opened_file.write("    color: black;\n")
            self.opened_file.write("    display: none;\n")
            self.opened_file.write("    padding: 50px;\n")
            self.opened_file.write("    text-align: left;\n")
            self.opened_file.write("}\n")
            self.opened_file.write("\n")
            self.opened_file.write("/* Style each tab content individually */\n")
            self.opened_file.write("#statistic {background-color: white;}\n")
            self.opened_file.write("#component {background-color: white;}\n")
            self.opened_file.write("#images {background-color: white;}\n")
            self.opened_file.write("   </STYLE>\n")
            self.opened_file.write("</HEAD>\n")
        def endHtml(self):
            self.opened_file.write("</HTML>\n")
        def beginBody(self, tab=None):
            self.opened_file.write("<BODY>\n")
            self.opened_file.write("<a name='top'/>\n")

        def addApplicationTab(self):
            if tab:
                self.opened_file.write('   <button class="tablink" onclick="openTab(\'statistic\', this)" id="defaultOpen">Main Statistics</button>\n')
                self.opened_file.write('   <button class="tablink" onclick="openTab(\'component\', this)">Main Components CVE / CVS</button>\n')
                self.opened_file.write('   <button class="tablink" onclick="openTab(\'images\', this)">Image CVE / CVS</button>\n')
            self.opened_file.write("\n")
        def endBody(self, tab=None):
            if tab:
                self.opened_file.write('<SCRIPT TYPE="text/javascript">\n')
                self.opened_file.write('function openTab(Name, elmnt) {\n')
                self.opened_file.write('    // Hide all elements with class="tabcontent" by default */\n')
                self.opened_file.write('    var i, tabcontent, tablinks;\n')
                self.opened_file.write('    tabcontent = document.getElementsByClassName("tabcontent");\n')
                self.opened_file.write('    for (i = 0; i < tabcontent.length; i++) {\n')
                self.opened_file.write('        tabcontent[i].style.display = "none";\n')
                self.opened_file.write('    }\n')
                self.opened_file.write('\n')
                self.opened_file.write('    // Remove the background color of all tablinks/buttons\n')
                self.opened_file.write('    tablinks = document.getElementsByClassName("tablink");\n')
                self.opened_file.write('    for (i = 0; i < tablinks.length; i++) {\n')
                self.opened_file.write('        tablinks[i].style.backgroundColor = "";\n')
                self.opened_file.write('    }\n')
                self.opened_file.write('\n')
                self.opened_file.write('    // Show the specific tab content\n')
                self.opened_file.write('    document.getElementById(Name).style.display = "block";\n')
                self.opened_file.write('\n')
                self.opened_file.write('    // Add the specific color to the button used to open the tab content\n')
                self.opened_file.write('    elmnt.style.backgroundColor = \'white\';\n')
                self.opened_file.write('    elmnt.style.color = "black";\n')
                self.opened_file.write('}\n')
                self.opened_file.write('\n')

                self.opened_file.write('function toggleunpatched(element) {\n')
                self.opened_file.write('    patched = document.getElementsByClassName("patched");\n')
                self.opened_file.write('    for (i = 0; i < patched.length; i++) {\n')
                self.opened_file.write('        if (element.checked) {\n')
                self.opened_file.write('            patched[i].style.display = "none";\n')
                self.opened_file.write('        } else {\n')
                self.opened_file.write('            patched[i].style.display = "block";\n')
                self.opened_file.write('        }\n')
                self.opened_file.write('    }\n')
                self.opened_file.write('}\n')

                self.opened_file.write('function toggleunscorev3(element) {\n')
                self.opened_file.write('    score = document.getElementsByClassName("scorev3");\n')
                self.opened_file.write('    for (i = 0; i < score.length; i++) {\n')
                self.opened_file.write('        if (element.checked) {\n')
                self.opened_file.write('            score[i].style.display = "none";\n')
                self.opened_file.write('        } else {\n')
                self.opened_file.write('            score[i].style.display = "block";\n')
                self.opened_file.write('        }\n')
                self.opened_file.write('    }\n')
                self.opened_file.write('    if element.checked == false) {\n')
                self.opened_file.write('        check = document.getElementsByName("check_unpatched")\n')
                self.opened_file.write('        toggleunpatched(check[0])\n')
                self.opened_file.write('    }\n')
                self.opened_file.write('}\n')

                self.opened_file.write('function toggleunscorev2(element) {\n')
                self.opened_file.write('    score2 = document.getElementsByClassName("scorev2");\n')
                self.opened_file.write('    for (i = 0; i < score2.length; i++) {\n')
                self.opened_file.write('        if (element.checked) {\n')
                self.opened_file.write('            score2[i].style.display = "none";\n')
                self.opened_file.write('        } else {\n')
                self.opened_file.write('            score2[i].style.display = "block";\n')
                self.opened_file.write('        }\n')
                self.opened_file.write('    }\n')
                self.opened_file.write('    if element.checked == false) {\n')
                self.opened_file.write('        check = document.getElementsByName("check_unpatched")\n')
                self.opened_file.write('        toggleunpatched(check[0])\n')
                self.opened_file.write('    }\n')
                self.opened_file.write('}\n')


                self.opened_file.write('// Get the element with id="defaultOpen" and click on it\n')
                self.opened_file.write('document.getElementById("defaultOpen").click();\n')
                self.opened_file.write('</SCRIPT>\n')
            else:
                self.opened_file.write('<SCRIPT TYPE="text/javascript">\n')
                self.opened_file.write('    // display all elements with class="tabcontent" by default */\n')
                self.opened_file.write('    var i, tabcontent, tablinks;\n')
                self.opened_file.write('    tabcontent = document.getElementsByClassName("tabcontent");\n')
                self.opened_file.write('    for (i = 0; i < tabcontent.length; i++) {\n')
                self.opened_file.write('        tabcontent[i].style.display = "block";\n')
                self.opened_file.write('    }\n')
                self.opened_file.write('\n')
                self.opened_file.write('</SCRIPT>\n')

            self.opened_file.write("</BODY>\n")

    def score_v2_table(score):
        ''' source : https://nvd.nist.gov/vuln-metrics/cvss '''
        if float(score) < 4.0:
            return "<SPAN STYLE='color: black; background-color: yellow;'> {} Low </SPAN>".format(score)
        elif float(score) < 7.0:
            return "<SPAN STYLE='color: black; background-color: #FFBF00;'> {} Medium </SPAN>".format(score)
        else:
            return "<SPAN STYLE='color: black; background-color: red;'> {} Hight </SPAN>".format(score)

    def score_v3_table(score):
        ''' source : https://www.cert-ist.com/public/fr/SO_detail?code=cvss%20v3&format=html '''
        if float(score) == 0.0:
            return "<SPAN STYLE='color: black; background-color: darkgrey;'> {} None </SPAN>".format(score)
        elif float(score) < 4.0:
            return "<SPAN STYLE='color: black; background-color: yellow;'> {} Low </SPAN>".format(score)
        elif float(score) < 7.0:
            return "<SPAN STYLE='color: black; background-color: #FFBF00;'> {} Medium </SPAN>".format(score)
        elif float(score) < 9.0:
            return "<SPAN STYLE='color: black; background-color: red;'> {} High </SPAN>".format(score)
        else:
            return "<SPAN STYLE='color: white; background-color: black;'> {} Critical </SPAN>".format(score)

    def generate_image_cve_sheet(html):
        html.startDiv("images", "Image CVE / CVS")
        html.addAnchor("images")

        # link
        html.addTitle("List of components on image:")
        html.startTable(style="width: 80%; border: 1px solid black;")
        html.startRow()
        html.addContent("<TD width='20%'>")
        count=0
        col=0
        with open(os.path.join(deploy_image_dir, "{}.json".format(ref_image_name))) as image_file:
            json_component = json.load(image_file)
            for i in json_component['package']:
                issue=i['issue']
                if len(issue) > 0:
                    html.addContent("<LI><a href='#image_{}'>{}</a></LI>\n".format(i['name'], i['name']))
                    count+=1
                    if count > 15:
                        count = 0
                        if col > 5:
                            col = 0
                            html.addContent("</td></tr><tr><td witdh='20%'>")
                        else:
                            html.addContent("</td><td witdh='10%'>")
                            col+=1
            html.addContent("</TD>")
            html.stopRow()
            html.stopTable()

        html.addNewLine()
        html.addNewLine()

        html.startTable(style="border: 1px solid black;")

        with open(os.path.join(deploy_image_dir, ref_image_name + ".json")) as image_file:
            json_component = json.load(image_file)
            for i in json_component['package']:
                issue=i['issue']
                if len(issue) > 0:
                    html.startRow()
                    html.addColumnHeaderContent("Component Name <a href='#top'>[top]</a><a name='image_{}'/>".format(i['name']), style="font-weight: bold; background-color: #cccccc;")
                    html.addColumnHeaderContent("Version", style="font-weight: bold; background-color: #cccccc;")
                    html.addColumnHeaderContent("CVE Ref Name", style="font-weight: bold; background-color: #cccccc;")
                    html.stopRow()
                    html.startRow()
                    html.addColumnContent(i['name'])
                    html.addColumnContent(i['version'])
                    html.addColumnContent(i['products'][0]['product'])
                    html.stopRow()

                    html.startRow()
                    html.addColumnHeaderContent("Issues", style="font-weight: bold; background-color: #cccccc;")
                    html.addContent("<TD colspan='2'>")
                    for iss in issue:
                        classe = ''
                        if iss['status'].find("Unpatched") < 0:
                            classe += 'patched '
                        if float(iss['scorev3']) < 7.0 :
                            classe += 'scorev3 '
                        if float(iss['scorev2']) < 7.0 :
                            classe += 'scorev2 '
                        if len(classe) > 0:
                            html.startTable(style='border: 1px solid black; width=100%;', classes=classe)
                        else:
                            html.startTable(style='border: 1px solid black; width=100%;')
                        html.startRow()
                        html.addColumnContent(iss['id'], style="width: 10%;")
                        if iss['status'].find("Unpatched") > -1:
                            html.addColumnContent(iss['status'], style="background-color: red;")
                        else:
                            html.addColumnContent(iss['status'])
                        html.stopRow()
                        html.startRow()
                        html.addColumnContent("")
                        html.addColumnContent(iss['summary'])
                        html.stopRow()
                        html.startRow()
                        html.addColumnContent("")
                        html.addColumnContent("ScoreV2 = {}  ScoreV3 = {}".format(score_v2_table(iss['scorev2']), score_v3_table(iss['scorev3'])))
                        html.stopRow()
                        html.startRow()
                        html.addColumnContent("")
                        html.addColumnContent("Link: <A HREF='{}'>NVD</A> or <A HREF='https://www.cve.org/CVERecord?id={}'>CVE.org</A>".format(iss['link'], iss['id']))
                        html.stopRow()
                        html.stopTable()
                    html.addContent("</TD>")
                    html.stopRow()

                    html.startRow()
                    html.stopRow()
                    html.startRow(style="bgcolor: gray;")
                    html.stopRow()
                    html.startRow()
                    html.stopRow()


        html.stopTable()
        html.stopDiv()

    def generate_statistics_sheet(html, components):
        general_MACHINE = d.getVar("MACHINE")
        # Make sure to remove any DISTRO append to IMAGE_BASENAME for short display
        general_IMAGE = re.sub(r'-%s$' % d.getVar('DISTRO'), '', d.getVar("IMAGE_BASENAME"))
        general_DISTRO = d.getVar("DISTRO")
        general_DISTRO_VERSION = d.getVar("DISTRO_VERSION")
        general_DISTRO_CODENAME = d.getVar("DISTRO_CODENAME")

        html.startDiv("statistic", "Main Statistics")
        html.addAnchor("statistic")

        html.addTitle("Number of CVE/CVS:")
        html.startTable()
        html.startRow()
        html.addColumnHeaderContent("Component Name", style="font-weight: bold; background-color: #cccccc;")
        html.addColumnHeaderContent("Issues", style="font-weight: bold; background-color: #cccccc;")
        html.addColumnHeaderContent("Issues Patched", style="font-weight: bold; background-color: #cccccc;")
        html.addColumnHeaderContent("Issues Unpatched", style="font-weight: bold; background-color: #cccccc;")
        html.stopRow()

        data = []
        for c in components.split(','):
            cvs = 0
            patched = 0
            unpatched = 0
            file_name = os.path.join(cve_deploy_dir, "%s_cve.json" % c.lstrip().rstrip())
            try:
                with open(os.path.join(cve_deploy_dir, file_name)) as component_file:
                    json_component = json.load(component_file)
                    for i in json_component['package']:
                        issue=i['issue']
                        cvs = len(issue)
                        for err in issue:
                            if err['status'].find("Patched") > -1:
                                patched+= 1
                            elif err['status'].find("Unpatched") > -1:
                                unpatched+= 1
                        data.append([i['name'], cvs, patched, unpatched])
            except FileNotFoundError:
                bb.note("file (%s) are not present" % os.path.join(cve_deploy_dir, "%s_cve.json" % c.lstrip().rstrip()))

        for i in data:
            html.startRow()
            html.addColumnContent(i[0], style="width: 10%;")
            html.addColumnContent(i[1], style="width: 10%; text-align: center;")
            html.addColumnContent(i[2], style="text-align: center;")
            html.addColumnContent(i[3], style="text-align: center;")
            html.stopRow()
        html.stopTable()

        html.addNewLine()
        html.addNewLine()

        # image count
        with open( os.path.join(deploy_image_dir, "{}.json".format(ref_image_name))) as image_file:
            json_component = json.load(image_file)
            cvs = 0
            package=0
            patched = 0
            unpatched = 0

            for i in json_component['package']:
                package += 1
                issue=i['issue']
                cvs += len(issue)
                for err in issue:
                    if err['status'].find("Patched") > -1:
                        patched += 1
                    elif err['status'].find("Unpatched") > -1:
                        unpatched += 1

        # package, cvs, patched, unpatched
        html.addTitle("Number of CVE/CVS for image:")
        html.startTable()
        html.startRow()
        html.addColumnHeaderContent("Image Name", style="font-weight: bold; background-color: #cccccc;")
        html.addColumnHeaderContent("Packages", style="font-weight: bold; background-color: #cccccc;")
        html.addColumnHeaderContent("Issues", style="font-weight: bold; background-color: #cccccc;")
        html.addColumnHeaderContent("Issues Patched", style="font-weight: bold; background-color: #cccccc;")
        html.addColumnHeaderContent("Issues Unpatched", style="font-weight: bold; background-color: #cccccc;")
        html.stopRow()

        html.startRow()
        html.addColumnContent(ref_image_name, style="width: 25%; ")
        html.addColumnContent(package, style="width: 10%; text-align: center;")
        html.addColumnContent(cvs, style="text-align: center;")
        html.addColumnContent(patched, style="text-align: center;")
        html.addColumnContent(unpatched, style="text-align: center;")
        html.stopRow()
        html.stopTable()

        html.stopDiv()

    def generate_components_content_sheet(html, components):
        html.startDiv("component", "Main Components CVE / CVS")
        html.addAnchor("component")

        html.addTitle("List of components:")

        # link
        for c in components.split(","):
            html.addContent("<LI><a href='#component_{}'>{}</a></LI>\n".format(c, c))

        html.addNewLine()
        html.addNewLine()
        for name in components.split(","):
            html.addContent("<H1>Component: {} <a href='#top'>[top]</a></H1>\n".format(name))
            html.addContent("<a name='component_{}'/>\n".format(name))
            html.startTable(style="border: 1px solid black;")
            html.startRow()
            html.addColumnHeaderContent("Component Name", style="font-weight: bold; background-color: #cccccc;")
            html.addColumnContent(name)
            html.stopRow()
            try:
                with open(os.path.join(cve_deploy_dir, "%s_cve.json" % name.lstrip().rstrip())) as component_file:
                    json_component = json.load(component_file)
                    for i in json_component['package']:
                        issue=i['issue']
                        html.startRow()
                        html.addColumnHeaderContent("Version", style="font-weight: bold; background-color: #cccccc;")
                        html.addColumnContent(i['version'])
                        html.stopRow()
                        html.startRow()
                        html.addColumnHeaderContent("CVE Ref Name", style="font-weight: bold; background-color: #cccccc;")
                        html.addColumnContent(i['products'][0]['product'])
                        html.stopRow()
                        html.startRow()
                        html.addColumnHeaderContent("Issues", style="font-weight: bold; background-color: #cccccc;")
                        html.startColumn()
                        for iss in issue:
                            classe = ''
                            if iss['status'].find("Unpatched") < 0:
                                classe += 'patched '
                            if float(iss['scorev3']) < 7.0 :
                                classe += 'scorev3 '
                            if float(iss['scorev2']) < 7.0 :
                                classe += 'scorev2 '
                            if len(classe) > 0:
                                html.startTable(style='border: 1px solid black; width=100%;', classes=classe)
                            else:
                                html.startTable(style='border: 1px solid black; width=100%;')
                            html.startRow()
                            html.addColumnContent(iss['id'], style="width: 10%;")
                            if iss['status'].find("Unpatched") > -1:
                                html.addColumnContent(iss['status'], style="background-color: red;")
                            else:
                                html.addColumnContent(iss['status'])
                            html.stopRow()
                            html.startRow()
                            html.addColumnContent("")
                            html.addColumnContent(iss['summary'])
                            html.stopRow()
                            html.startRow()
                            html.addColumnContent("")
                            html.addColumnContent("ScoreV2 = {}; ScoreV3 = {}".format(score_v2_table(iss['scorev2']), score_v3_table(iss['scorev3'])))
                            html.stopRow()
                            html.startRow()
                            html.addColumnContent("")
                            html.addColumnContent("Link: <A HREF='{}'>NVD</A> or <A HREF='https://www.cve.org/CVERecord?id={}'>CVE.org</A>".format(iss['link'], iss['id']))
                            html.stopRow()
                            # empty line for separation
                            html.startRow(style="bgcolor: gray;")
                            html.stopRow()
                            html.stopTable()
                        html.stopColumn()
                        i = None
            except FileNotFoundError:
                bb.note("file (%s) are not present" % os.path.join(cve_deploy_dir, "%s_cve.json" % name.lstrip().rstrip()))

            html.stopTable()
        html.stopDiv()

    # Create license summary file
    cve_summary_name_path = os.path.join(cve_summary_deploydir, cve_summary_name)
    print("generate ", cve_summary_name_path)
    html = HTMLSummaryfile()
    html.openfile(cve_summary_name_path)
    html.beginHtml()
    html.beginBody(with_tab)

    html.addTitle("Image Name: {}<BR/>Generation Date: {}".format(ref_image_name, datetime))

    html.addContent("<div class='one'>See Only 'Unpatched' CVE <input type='checkbox' valud='submit' class='btn' name='unpatched' onclick='toggleunpatched(this)'></div>")
    html.addNewLine()
    html.addContent("<div class='one'>See Only 'ScoreV3 > 7' (only)<input type='checkbox' valud='submit' class='btn' onclick='toggleunscorev3(this)'></div>")
    html.addNewLine()
    html.addContent("<div class='one'>See Only 'ScoreV2 > 7' (only)<input type='checkbox' valud='submit' class='btn' onclick='toggleunscorev2(this)'></div>")
    html.addNewLine()
    html.addApplicationTab()

    ''' generate first page: statistics cve / cvs information'''
    generate_statistics_sheet(html, components_list)
    ''' generate image content '''
    generate_components_content_sheet(html, components_list)
    ''' generate license spdx reference '''
    generate_image_cve_sheet(html)
    html.endBody(with_tab)
    html.endHtml()
    html.closefile()

    # Create link
    cve_summary_link_path = os.path.join(cve_summary_deploydir, cve_summary_link)
    if os.path.exists(cve_summary_name_path):
        bb.note("Creating symlink: %s -> %s" % (cve_summary_link_path, cve_summary_name))
        if os.path.islink(cve_summary_link_path):
            os.remove(cve_summary_link_path)
        os.symlink(cve_summary_name, cve_summary_link_path)
    else:
        bb.note("Skipping symlink, source does not exist: %s -> %s" % (cve_summary_link_path, cve_summary_name))


python do_st_write_cve_create_summary() {
    bb.note("---> ENABLE_IMAGE_CVE_SUMMARY %s" % (d.getVar('ENABLE_IMAGE_CVE_SUMMARY')))
    if d.getVar('ENABLE_IMAGE_CVE_SUMMARY') == "1":
        if not d.getVar('CVE_CHECK_MANIFEST') is None:
            cve_create_summary(d)
    else:
        return
}
addtask st_write_cve_create_summary before do_build after do_image_complete
do_st_write_cve_create_summary[dirs] = "${ST_CVE_SUMMARY_DIR} ${IMGDEPLOYDIR}"

SSTATETASKS += "do_st_write_cve_create_summary"
do_st_write_cve_create_summary[cleandirs] = "${ST_CVE_SUMMARY_DIR}"
do_st_write_cve_create_summary[sstate-inputdirs] = "${ST_CVE_SUMMARY_DIR}"
do_st_write_cve_create_summary[sstate-outputdirs] = "${ST_CVE_SUMMARY_DEPLOYDIR}/"

python do_st_write_cve_create_summary_setscene () {
    sstate_setscene(d)
}
addtask do_st_write_cve_create_summary_setscene

#excluded from basehash signature calculation
cve_create_summary[vardepsexclude] += "DATETIME"

