# This class integrates real-time license scanning, generation of SPDX standard
# output and verifiying license info during the building process.
# It is a combination of efforts from the OE-Core, SPDX and Fossology projects.
#
# For more information on FOSSology:
#   http://www.fossology.org
#
# For more information on FOSSologySPDX commandline:
#   https://github.com/spdx-tools/fossology-spdx/wiki/Fossology-SPDX-Web-API
#
# For more information on SPDX:
#   http://www.spdx.org
#

# SPDX file will be output to the path which is defined as[SPDX_MANIFEST_DIR] 
# in ./meta/conf/licenses.conf.

SPDXSSTATEDIR = "${WORKDIR}/spdx_sstate_dir"

# If ${S} isn't actually the top-level source directory, set SPDX_S to point at
# the real top-level directory.
SPDX_S ?= "${S}"

python do_spdx () {
    import os, sys
    import json, shutil

    info = {} 
    info['workdir'] = d.getVar('WORKDIR', True)
    info['sourcedir'] = d.getVar('SPDX_S', True)
    info['pn'] = d.getVar('PN', True)
    info['pv'] = d.getVar('PV', True)
    info['spdx_version'] = d.getVar('SPDX_VERSION', True)
    info['data_license'] = d.getVar('DATA_LICENSE', True)

    sstatedir = d.getVar('SPDXSSTATEDIR', True)
    sstatefile = os.path.join(sstatedir, info['pn'] + info['pv'] + ".spdx")

    manifest_dir = d.getVar('SPDX_MANIFEST_DIR', True)
    info['outfile'] = os.path.join(manifest_dir, info['pn'] + ".spdx" )

    info['spdx_temp_dir'] = d.getVar('SPDX_TEMP_DIR', True)
    info['tar_file'] = os.path.join(info['workdir'], info['pn'] + ".tar.gz" )

    # Make sure important dirs exist
    try:
        bb.utils.mkdirhier(manifest_dir)
        bb.utils.mkdirhier(sstatedir)
        bb.utils.mkdirhier(info['spdx_temp_dir'])
    except OSError as e:
        bb.error("SPDX: Could not set up required directories: " + str(e))
        return

    ## get everything from cache.  use it to decide if 
    ## something needs to be rerun 
    cur_ver_code = get_ver_code(info['sourcedir'])
    cache_cur = False
    if os.path.exists(sstatefile):
        ## cache for this package exists. read it in
        cached_spdx = get_cached_spdx(sstatefile)

        if cached_spdx['PackageVerificationCode'] == cur_ver_code:
            bb.warn("SPDX: Verification code for " + info['pn']
                  + "is same as cache's. do nothing")
            cache_cur = True
        else:
            local_file_info = setup_foss_scan(info, True, cached_spdx['Files'])
    else:
        local_file_info = setup_foss_scan(info, False, None)

    if cache_cur:
        spdx_file_info = cached_spdx['Files']
        foss_package_info = cached_spdx['Package']
        foss_license_info = cached_spdx['Licenses']
    else:
        ## setup fossology command
        foss_server = d.getVar('FOSS_SERVER', True)
        foss_flags = d.getVar('FOSS_WGET_FLAGS', True)
        foss_full_spdx = d.getVar('FOSS_FULL_SPDX', True) == "true" or False
        foss_command = "wget %s --post-file=%s %s"\
            % (foss_flags, info['tar_file'], foss_server)
        
        foss_result = run_fossology(foss_command, foss_full_spdx)
        if foss_result is not None:
            (foss_package_info, foss_file_info, foss_license_info) = foss_result
            spdx_file_info = create_spdx_doc(local_file_info, foss_file_info)
            ## write to cache
            write_cached_spdx(sstatefile, cur_ver_code, foss_package_info,
                              spdx_file_info, foss_license_info)
        else:
            bb.error("SPDX: Could not communicate with FOSSology server. Command was: " + foss_command)
            return
    
    ## Get document and package level information
    spdx_header_info = get_header_info(info, cur_ver_code, foss_package_info)
    
    ## CREATE MANIFEST
    create_manifest(info, spdx_header_info, spdx_file_info, foss_license_info)

    ## clean up the temp stuff
    shutil.rmtree(info['spdx_temp_dir'], ignore_errors=True)
    if os.path.exists(info['tar_file']):
        remove_file(info['tar_file'])
}
addtask spdx after do_patch before do_configure

def create_manifest(info, header, files, licenses):
    import codecs
    with codecs.open(info['outfile'], mode='w', encoding='utf-8') as f:
        # Write header
        f.write(header + '\n')

        # Write file data
        for chksum, block in files.iteritems():
            f.write("FileName: " + block['FileName'] + '\n')
            for key, value in block.iteritems():
                if not key == 'FileName':
                    f.write(key + ": " + value + '\n')
            f.write('\n')

        # Write license data
        for id, block in licenses.iteritems():
            f.write("LicenseID: " + id + '\n')
            for key, value in block.iteritems():
                f.write(key + ": " + value + '\n')
            f.write('\n')

def get_cached_spdx(sstatefile):
    import json
    import codecs
    cached_spdx_info = {}
    with codecs.open(sstatefile, mode='r', encoding='utf-8') as f:
        try:
            cached_spdx_info = json.load(f)
        except ValueError as e:
            cached_spdx_info = None
    return cached_spdx_info

def write_cached_spdx(sstatefile, ver_code, package_info, files, license_info):
    import json
    import codecs
    spdx_doc = {}
    spdx_doc['PackageVerificationCode'] = ver_code
    spdx_doc['Files'] = {}
    spdx_doc['Files'] = files
    spdx_doc['Package'] = {}
    spdx_doc['Package'] = package_info
    spdx_doc['Licenses'] = {}
    spdx_doc['Licenses'] = license_info
    with codecs.open(sstatefile, mode='w', encoding='utf-8') as f:
        f.write(json.dumps(spdx_doc))

def setup_foss_scan(info, cache, cached_files):
    import errno, shutil
    import tarfile
    file_info = {}
    cache_dict = {}

    for f_dir, f in list_files(info['sourcedir']):
        full_path = os.path.join(f_dir, f)
        abs_path = os.path.join(info['sourcedir'], full_path)
        dest_dir = os.path.join(info['spdx_temp_dir'], f_dir)
        dest_path = os.path.join(info['spdx_temp_dir'], full_path)

        checksum = hash_file(abs_path)
        if not checksum is None:
            file_info[checksum] = {}
            ## retain cache information if it exists
            if cache and checksum in cached_files:
                file_info[checksum] = cached_files[checksum]
            ## have the file included in what's sent to the FOSSology server
            else:
                file_info[checksum]['FileName'] = full_path
                try:
                    bb.utils.mkdirhier(dest_dir)
                    shutil.copyfile(abs_path, dest_path)
                except OSError as e:
                    bb.warn("SPDX: mkdirhier failed: " + str(e))
                except shutil.Error as e:
                    bb.warn("SPDX: copyfile failed: " + str(e))
                except IOError as e:
                    bb.warn("SPDX: copyfile failed: " + str(e))
        else:
            bb.warn("SPDX: Could not get checksum for file: " + f)
    
    with tarfile.open(info['tar_file'], "w:gz") as tar:
        tar.add(info['spdx_temp_dir'], arcname=os.path.basename(info['spdx_temp_dir']))
    
    return file_info

def remove_file(file_name):
    try:
        os.remove(file_name)
    except OSError as e:
        pass

def list_files(dir):
    for root, subFolders, files in os.walk(dir):
        for f in files:
            rel_root = os.path.relpath(root, dir)
            yield rel_root, f
    return

def hash_file(file_name):
    try:
        with open(file_name, 'rb') as f:
            data_string = f.read()
            sha1 = hash_string(data_string)
            return sha1
    except:
        return None

def hash_string(data):
    import hashlib
    sha1 = hashlib.sha1()
    sha1.update(data)
    return sha1.hexdigest()

def run_fossology(foss_command, full_spdx):
    import string, re
    import subprocess
    
    p = subprocess.Popen(foss_command.split(),
        stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    foss_output, foss_error = p.communicate()
    if p.returncode != 0:
        return None

    foss_output = unicode(foss_output, "utf-8")
    foss_output = string.replace(foss_output, '\r', '')

    # Package info
    package_info = {}
    if full_spdx:
        # All mandatory, only one occurance
        package_info['PackageCopyrightText'] = re.findall('PackageCopyrightText: (.*?</text>)', foss_output, re.S)[0]
        package_info['PackageLicenseDeclared'] = re.findall('PackageLicenseDeclared: (.*)', foss_output)[0]
        package_info['PackageLicenseConcluded'] = re.findall('PackageLicenseConcluded: (.*)', foss_output)[0]
        # These may be more than one
        package_info['PackageLicenseInfoFromFiles'] = re.findall('PackageLicenseInfoFromFiles: (.*)', foss_output)
    else:
        DEFAULT = "NOASSERTION"
        package_info['PackageCopyrightText'] = "<text>" + DEFAULT + "</text>"
        package_info['PackageLicenseDeclared'] = DEFAULT
        package_info['PackageLicenseConcluded'] = DEFAULT
        package_info['PackageLicenseInfoFromFiles'] = []

    # File info
    file_info = {}
    records = []
    # FileName is also in PackageFileName, so we match on FileType as well.
    records = re.findall('FileName:.*?FileType:.*?</text>', foss_output, re.S)
    for rec in records:
        chksum = re.findall('FileChecksum: SHA1: (.*)\n', rec)[0]
        file_info[chksum] = {}
        file_info[chksum]['FileCopyrightText'] = re.findall('FileCopyrightText: '
            + '(.*?</text>)', rec, re.S )[0]
        fields = ['FileName', 'FileType', 'LicenseConcluded', 'LicenseInfoInFile']
        for field in fields:
            file_info[chksum][field] = re.findall(field + ': (.*)', rec)[0]

    # Licenses
    license_info = {}
    licenses = []
    licenses = re.findall('LicenseID:.*?LicenseName:.*?\n', foss_output, re.S)
    for lic in licenses:
        license_id = re.findall('LicenseID: (.*)\n', lic)[0]
        license_info[license_id] = {}
        license_info[license_id]['ExtractedText'] = re.findall('ExtractedText: (.*?</text>)', lic, re.S)[0]
        license_info[license_id]['LicenseName'] = re.findall('LicenseName: (.*)', lic)[0]

    return (package_info, file_info, license_info)

def create_spdx_doc(file_info, scanned_files):
    import json
    ## push foss changes back into cache
    for chksum, lic_info in scanned_files.iteritems():
        if chksum in file_info:
            file_info[chksum]['FileType'] = lic_info['FileType']
            file_info[chksum]['FileChecksum: SHA1'] = chksum
            file_info[chksum]['LicenseInfoInFile'] = lic_info['LicenseInfoInFile']
            file_info[chksum]['LicenseConcluded'] = lic_info['LicenseConcluded']
            file_info[chksum]['FileCopyrightText'] = lic_info['FileCopyrightText']
        else:
            bb.warn("SPDX: " + lic_info['FileName'] + " : " + chksum
                + " : is not in the local file info: "
                + json.dumps(lic_info, indent=1))
    return file_info

def get_ver_code(dirname):
    chksums = []
    for f_dir, f in list_files(dirname):
        hash = hash_file(os.path.join(dirname, f_dir, f))
        if not hash is None:
            chksums.append(hash)
        else:
            bb.warn("SPDX: Could not hash file: " + path)
    ver_code_string = ''.join(chksums).lower()
    ver_code = hash_string(ver_code_string)
    return ver_code

def get_header_info(info, spdx_verification_code, package_info):
    """
        Put together the header SPDX information.
        Eventually this needs to become a lot less
        of a hardcoded thing.
    """
    from datetime import datetime
    import os
    head = []
    DEFAULT = "NOASSERTION"

    package_checksum = hash_file(info['tar_file'])
    if package_checksum is None:
        package_checksum = DEFAULT

    ## document level information
    head.append("## SPDX Document Information")
    head.append("SPDXVersion: " + info['spdx_version'])
    head.append("DataLicense: " + info['data_license'])
    head.append("DocumentComment: <text>SPDX for "
        + info['pn'] + " version " + info['pv'] + "</text>")
    head.append("")

    ## Creator information
    ## Note that this does not give time in UTC.
    now = datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
    head.append("## Creation Information")
    ## Tools are supposed to have a version, but FOSSology+SPDX provides none.
    head.append("Creator: Tool: FOSSology+SPDX")
    head.append("Created: " + now)
    head.append("CreatorComment: <text>UNO</text>")
    head.append("")

    ## package level information
    head.append("## Package Information")
    head.append("PackageName: " + info['pn'])
    head.append("PackageVersion: " + info['pv'])
    head.append("PackageFileName: " + os.path.basename(info['tar_file']))
    head.append("PackageSupplier: Person:" + DEFAULT)
    head.append("PackageDownloadLocation: " + DEFAULT)
    head.append("PackageSummary: <text></text>")
    head.append("PackageOriginator: Person:" + DEFAULT)
    head.append("PackageChecksum: SHA1: " + package_checksum)
    head.append("PackageVerificationCode: " + spdx_verification_code)
    head.append("PackageDescription: <text>" + info['pn']
        + " version " + info['pv'] + "</text>")
    head.append("")
    head.append("PackageCopyrightText: "
        + package_info['PackageCopyrightText'])
    head.append("")
    head.append("PackageLicenseDeclared: "
        + package_info['PackageLicenseDeclared'])
    head.append("PackageLicenseConcluded: "
        + package_info['PackageLicenseConcluded'])

    for licref in package_info['PackageLicenseInfoFromFiles']:
        head.append("PackageLicenseInfoFromFiles: " + licref)
    head.append("")
    
    ## header for file level
    head.append("## File Information")
    head.append("")

    return '\n'.join(head)
