#!/usr/bin/env python

import sys
import os
import re
import anchore.anchore_utils

def perform_cve_scan_simple(severity='all'):
    severity = severity
    ret = {}
    warns = list()
    cve_data_context = {}
    for imageId in config['images']:
        image = allimages[imageId]
        try:
            cve_data = anchore.anchore_utils.cve_load_data(image, cve_data_context=cve_data_context)
        except ValueError as err:
            warns.append(image.meta['shortId']+" ("+image.get_human_name()+") " + str(err))
            cve_data = None

        earliest_vulnerable = None
        if cve_data:
            cve_results = anchore.anchore_utils.cve_scanimage(cve_data, image)
            if cve_results:
                for cveId in cve_results.keys():
                    if severity == 'all' or cve_results[cveId]['severity'] == severity:
                        if cveId not in ret:
                            ret[cveId] = {'severity':'Unknown', 'imageIds':list()}

                        outsev = "NA"
                        if 'severity' in cve_results[cveId]:
                            outsev = cve_results[cveId]['severity']

                        outurl = "NA"
                        if 'url' in cve_results[cveId]:
                            outurl = cve_results[cveId]['url']

                        ret[cveId]['severity'] = outsev
                        ret[cveId]['url'] = outurl
                        ret[cveId]['imageIds'].append(imageId)

        else:
            warns.append(image.meta['shortId']+" ("+image.get_human_name()+") cannot scan image: no CVE data loaded from feed")
                             
    return(ret, warns)

# main routine

# parse cmdline into config dict
try:
    config = anchore.anchore_utils.init_query_cmdline(sys.argv, "params: <Low|Medium|High|Critical|Unknown|Negligible> <another level> ...\nhelp: use 'all' to scan for all severity levels")
except Exception as err:
    print str(err)
    sys.exit(1)

# this means that no config is available, for example when 'help' is given as a parameter
if not config:
    sys.exit(0)

# handle default case if no params are given
if len(config['params']) <= 0:
    config['params'] = ['all']

# set up output list
outlist = list()
outlist.append(["*CVE_ID","Severity","Affected_Count", "Affected_Image_Ids", "URL"])
#outlist.append(["*CVEID","Severity","AffectedCount", "AffectedImageIDs"])

# perform query
allimages = {}
for imageId in config['images']:
    image = anchore.anchore_image.AnchoreImage(imageId, config['anchore_config']['image_data_store'], allimages)

    if imageId not in allimages:
        allimages[imageId] = image
        
try:
    warns = list()
    result = {}
    try:
        result, warns = perform_cve_scan_simple('all')
    except ValueError as err:
        print str(err)

    for k in result.keys():
        if 'all' in config['params'] or result[k]['severity'] in config['params']:
            outlist.append([k, result[k]['severity'], str(len(result[k]['imageIds'])), ' '.join(result[k]['imageIds']), result[k]['url']])
            #outlist.append([k, result[k]['severity'], str(len(result[k]['imageIds'])), ' '.join(result[k]['imageIds'])])
        
except Exception as err:
    print str(err)
    import traceback
    traceback.print_exc()

# save output list as output file for anchore to ingress
anchore.anchore_utils.write_kvfile_fromlist(config['output'], outlist)
if len(warns) > 0:
    anchore.anchore_utils.write_plainfile_fromlist(config['output_warns'], warns)

# cleanup and exit
allimages.clear()
sys.exit(0)
