# Copyright (c) 2020-2021 The Linux Foundation
#
# SPDX-License-Identifier: Apache-2.0

import os
import yaml

from west import log
from west.util import west_topdir, WestNotFound

from zspdx.cmakecache import parseCMakeCacheFile
from zspdx.cmakefileapijson import parseReply
from zspdx.datatypes import DocumentConfig, Document, File, PackageConfig, Package, RelationshipDataElementType, RelationshipData, Relationship
from zspdx.getincludes import getCIncludes
import zspdx.spdxids

# WalkerConfig contains configuration data for the Walker.
class WalkerConfig:
    def __init__(self):
        super(WalkerConfig, self).__init__()

        # prefix for Document namespaces; should not end with "/"
        self.namespacePrefix = ""

        # location of build directory
        self.buildDir = ""

        # should also analyze for included header files?
        self.analyzeIncludes = False

        # should also add an SPDX document for the SDK?
        self.includeSDK = False

# Walker is the main analysis class: it walks through the CMake codemodel,
# build files, and corresponding source and SDK files, and gathers the
# information needed to build the SPDX data classes.
class Walker:
    # initialize with WalkerConfig
    def __init__(self, cfg):
        super(Walker, self).__init__()

        # configuration - WalkerConfig
        self.cfg = cfg

        # the various Documents that we will be building
        self.docBuild = None
        self.docZephyr = None
        self.docApp = None
        self.docSDK = None

        # dict of absolute file path => the Document that owns that file
        self.allFileLinks = {}

        # queue of pending source Files to create, process and assign
        self.pendingSources = []

        # queue of pending relationships to create, process and assign
        self.pendingRelationships = []

        # parsed CMake codemodel
        self.cm = None

        # parsed CMake cache dict, once we have the build path
        self.cmakeCache = {}

        # C compiler path from parsed CMake cache
        self.compilerPath = ""

        # SDK install path from parsed CMake cache
        self.sdkPath = ""

    # primary entry point
    def makeDocuments(self):
        # parse CMake cache file and get compiler path
        log.inf("parsing CMake Cache file")
        self.getCacheFile()

        # check if meta file is generated
        if not self.metaFile:
            log.err("CONFIG_BUILD_OUTPUT_META must be enabled to generate spdx files; bailing")
            return False

        # parse codemodel from Walker cfg's build dir
        log.inf("parsing CMake Codemodel files")
        self.cm = self.getCodemodel()
        if not self.cm:
            log.err("could not parse codemodel from CMake API reply; bailing")
            return False

        # set up Documents
        log.inf("setting up SPDX documents")
        retval = self.setupDocuments()
        if not retval:
            return False

        # walk through targets in codemodel to gather information
        log.inf("walking through targets")
        self.walkTargets()

        # walk through pending sources and create corresponding files
        log.inf("walking through pending sources files")
        self.walkPendingSources()

        # walk through pending relationship data and create relationships
        log.inf("walking through pending relationships")
        self.walkRelationships()

        return True

    # parse cache file and pull out relevant data
    def getCacheFile(self):
        cacheFilePath = os.path.join(self.cfg.buildDir, "CMakeCache.txt")
        self.cmakeCache = parseCMakeCacheFile(cacheFilePath)
        if self.cmakeCache:
            self.compilerPath = self.cmakeCache.get("CMAKE_C_COMPILER", "")
            self.sdkPath = self.cmakeCache.get("ZEPHYR_SDK_INSTALL_DIR", "")
            self.metaFile =  self.cmakeCache.get("KERNEL_META_PATH", "")

    # determine path from build dir to CMake file-based API index file, then
    # parse it and return the Codemodel
    def getCodemodel(self):
        log.dbg("getting codemodel from CMake API reply files")

        # make sure the reply directory exists
        cmakeReplyDirPath = os.path.join(self.cfg.buildDir, ".cmake", "api", "v1", "reply")
        if not os.path.exists(cmakeReplyDirPath):
            log.err(f'cmake api reply directory {cmakeReplyDirPath} does not exist')
            log.err('was query directory created before cmake build ran?')
            return None
        if not os.path.isdir(cmakeReplyDirPath):
            log.err(f'cmake api reply directory {cmakeReplyDirPath} exists but is not a directory')
            return None

        # find file with "index" prefix; there should only be one
        indexFilePath = ""
        for f in os.listdir(cmakeReplyDirPath):
            if f.startswith("index"):
                indexFilePath = os.path.join(cmakeReplyDirPath, f)
                break
        if indexFilePath == "":
            # didn't find it
            log.err(f'cmake api reply index file not found in {cmakeReplyDirPath}')
            return None

        # parse it
        return parseReply(indexFilePath)

    def setupAppDocument(self):
        # set up app document
        cfgApp = DocumentConfig()
        cfgApp.name = "app-sources"
        cfgApp.namespace = self.cfg.namespacePrefix + "/app"
        cfgApp.docRefID = "DocumentRef-app"
        self.docApp = Document(cfgApp)

        # also set up app sources package
        cfgPackageApp = PackageConfig()
        cfgPackageApp.name = "app-sources"
        cfgPackageApp.spdxID = "SPDXRef-app-sources"
        # relativeBaseDir is app sources dir
        cfgPackageApp.relativeBaseDir = self.cm.paths_source
        pkgApp = Package(cfgPackageApp, self.docApp)
        self.docApp.pkgs[pkgApp.cfg.spdxID] = pkgApp

        # create DESCRIBES relationship data
        rd = RelationshipData()
        rd.ownerType = RelationshipDataElementType.DOCUMENT
        rd.ownerDocument = self.docApp
        rd.otherType = RelationshipDataElementType.PACKAGEID
        rd.otherPackageID = cfgPackageApp.spdxID
        rd.rlnType = "DESCRIBES"

        # add it to pending relationships queue
        self.pendingRelationships.append(rd)

    def setupBuildDocument(self):
        # set up build document
        cfgBuild = DocumentConfig()
        cfgBuild.name = "build"
        cfgBuild.namespace = self.cfg.namespacePrefix + "/build"
        cfgBuild.docRefID = "DocumentRef-build"
        self.docBuild = Document(cfgBuild)

        # we'll create the build packages in walkTargets()

        # the DESCRIBES relationship for the build document will be
        # with the zephyr_final package
        rd = RelationshipData()
        rd.ownerType = RelationshipDataElementType.DOCUMENT
        rd.ownerDocument = self.docBuild
        rd.otherType = RelationshipDataElementType.TARGETNAME
        rd.otherTargetName = "zephyr_final"
        rd.rlnType = "DESCRIBES"

        # add it to pending relationships queue
        self.pendingRelationships.append(rd)

    def setupZephyrDocument(self, modules):
        # set up zephyr document
        cfgZephyr = DocumentConfig()
        cfgZephyr.name = "zephyr-sources"
        cfgZephyr.namespace = self.cfg.namespacePrefix + "/zephyr"
        cfgZephyr.docRefID = "DocumentRef-zephyr"
        self.docZephyr = Document(cfgZephyr)

        # relativeBaseDir is Zephyr sources topdir
        try:
            relativeBaseDir = west_topdir(self.cm.paths_source)
        except WestNotFound:
            log.err(f"cannot find west_topdir for CMake Codemodel sources path {self.cm.paths_source}; bailing")
            return False

        # set up zephyr sources package
        cfgPackageZephyr = PackageConfig()
        cfgPackageZephyr.name = "zephyr-sources"
        cfgPackageZephyr.spdxID = "SPDXRef-zephyr-sources"
        cfgPackageZephyr.relativeBaseDir = relativeBaseDir

        pkgZephyr = Package(cfgPackageZephyr, self.docZephyr)
        self.docZephyr.pkgs[pkgZephyr.cfg.spdxID] = pkgZephyr

        for module in modules:
            module_name = module.get("name", None)
            module_path = module.get("path", None)

            if not module_name:
                log.err(f"cannot find module name in meta file; bailing")
                return False

            # Replace "_" by "-" since it's not allowed in spdx ID
            module_name = module_name.replace("_", "-")

            # set up zephyr sources package
            cfgPackageZephyrModule = PackageConfig()
            cfgPackageZephyrModule.name = module_name
            cfgPackageZephyrModule.spdxID = "SPDXRef-" + module_name + "-sources"
            cfgPackageZephyrModule.relativeBaseDir = module_path

            pkgZephyrModule = Package(cfgPackageZephyrModule, self.docZephyr)
            self.docZephyr.pkgs[pkgZephyrModule.cfg.spdxID] = pkgZephyrModule

        # create DESCRIBES relationship data
        rd = RelationshipData()
        rd.ownerType = RelationshipDataElementType.DOCUMENT
        rd.ownerDocument = self.docZephyr
        rd.otherType = RelationshipDataElementType.PACKAGEID
        rd.otherPackageID = cfgPackageZephyr.spdxID
        rd.rlnType = "DESCRIBES"

        # add it to pending relationships queue
        self.pendingRelationships.append(rd)

    def setupSDKDocument(self):
        # set up SDK document
        cfgSDK = DocumentConfig()
        cfgSDK.name = "sdk"
        cfgSDK.namespace = self.cfg.namespacePrefix + "/sdk"
        cfgSDK.docRefID = "DocumentRef-sdk"
        self.docSDK = Document(cfgSDK)

        # also set up zephyr sdk package
        cfgPackageSDK = PackageConfig()
        cfgPackageSDK.name = "sdk"
        cfgPackageSDK.spdxID = "SPDXRef-sdk"
        # relativeBaseDir is SDK dir
        cfgPackageSDK.relativeBaseDir = self.sdkPath
        pkgSDK = Package(cfgPackageSDK, self.docSDK)
        self.docSDK.pkgs[pkgSDK.cfg.spdxID] = pkgSDK

        # create DESCRIBES relationship data
        rd = RelationshipData()
        rd.ownerType = RelationshipDataElementType.DOCUMENT
        rd.ownerDocument = self.docSDK
        rd.otherType = RelationshipDataElementType.PACKAGEID
        rd.otherPackageID = cfgPackageSDK.spdxID
        rd.rlnType = "DESCRIBES"

        # add it to pending relationships queue
        self.pendingRelationships.append(rd)

    # set up Documents before beginning
    def setupDocuments(self):
        log.dbg("setting up placeholder documents")

        self.setupBuildDocument()

        try:
            with open(self.metaFile) as file:
                content = yaml.load(file.read(), yaml.SafeLoader)
                self.setupZephyrDocument(content["modules"])
        except (FileNotFoundError, yaml.YAMLError):
            log.err(f"cannot find a valid zephyr_meta.yml required for SPDX generation; bailing")
            return False

        self.setupAppDocument()

        if self.cfg.includeSDK:
            self.setupSDKDocument()

        return True

    # walk through targets and gather information
    def walkTargets(self):
        log.dbg("walking targets from codemodel")

        # assuming just one configuration; consider whether this is incorrect
        cfgTargets = self.cm.configurations[0].configTargets
        for cfgTarget in cfgTargets:
            # build the Package for this target
            pkg = self.initConfigTargetPackage(cfgTarget)

            # see whether this target has any build artifacts at all
            if len(cfgTarget.target.artifacts) > 0:
                # add its build file
                bf = self.addBuildFile(cfgTarget, pkg)

                # get its source files if build file is found
                if bf:
                    self.collectPendingSourceFiles(cfgTarget, pkg, bf)
            else:
                log.dbg(f"  - target {cfgTarget.name} has no build artifacts")

            # get its target dependencies
            self.collectTargetDependencies(cfgTargets, cfgTarget, pkg)

    # build a Package in the Build doc for the given ConfigTarget
    def initConfigTargetPackage(self, cfgTarget):
        log.dbg(f"  - initializing Package for target: {cfgTarget.name}")

        # create target Package's config
        cfg = PackageConfig()
        cfg.name = cfgTarget.name
        cfg.spdxID = "SPDXRef-" + zspdx.spdxids.convertToSPDXIDSafe(cfgTarget.name)
        cfg.relativeBaseDir = self.cm.paths_build

        # build Package
        pkg = Package(cfg, self.docBuild)

        # add Package to build Document
        self.docBuild.pkgs[cfg.spdxID] = pkg
        return pkg

    # create a target's build product File and add it to its Package
    # call with:
    #   1) ConfigTarget
    #   2) Package for that target
    # returns: File
    def addBuildFile(self, cfgTarget, pkg):
        # assumes only one artifact in each target
        artifactPath = os.path.join(pkg.cfg.relativeBaseDir, cfgTarget.target.artifacts[0])
        log.dbg(f"  - adding File {artifactPath}")
        log.dbg(f"    - relativeBaseDir: {pkg.cfg.relativeBaseDir}")
        log.dbg(f"    - artifacts[0]: {cfgTarget.target.artifacts[0]}")

        # don't create build File if artifact path points to nonexistent file
        if not os.path.exists(artifactPath):
            log.dbg(f"  - target {cfgTarget.name} lists build artifact {artifactPath} but file not found after build; skipping")
            return None

        # create build File
        bf = File(self.docBuild, pkg)
        bf.abspath = artifactPath
        bf.relpath = cfgTarget.target.artifacts[0]
        # can use nameOnDisk b/c it is just the filename w/out directory paths
        bf.spdxID = zspdx.spdxids.getUniqueFileID(cfgTarget.target.nameOnDisk, self.docBuild.timesSeen)
        # don't fill hashes / licenses / rlns now, we'll do that after walking

        # add File to Package
        pkg.files[bf.spdxID] = bf

        # add file path link to Document and global links
        self.docBuild.fileLinks[bf.abspath] = bf
        self.allFileLinks[bf.abspath] = self.docBuild

        # also set this file as the target package's build product file
        pkg.targetBuildFile = bf

        return bf

    # collect a target's source files, add to pending sources queue, and
    # create pending relationship data entry
    # call with:
    #   1) ConfigTarget
    #   2) Package for that target
    #   3) build File for that target
    def collectPendingSourceFiles(self, cfgTarget, pkg, bf):
        log.dbg(f"  - collecting source files and adding to pending queue")

        targetIncludesSet = set()

        # walk through target's sources
        for src in cfgTarget.target.sources:
            log.dbg(f"    - add pending source file and relationship for {src.path}")
            # get absolute path if we don't have it
            srcAbspath = src.path
            if not os.path.isabs(src.path):
                srcAbspath = os.path.join(self.cm.paths_source, src.path)

            # check whether it even exists
            if not (os.path.exists(srcAbspath) and os.path.isfile(srcAbspath)):
                log.dbg(f"  - {srcAbspath} does not exist but is referenced in sources for target {pkg.cfg.name}; skipping")
                continue

            # add it to pending source files queue
            self.pendingSources.append(srcAbspath)

            # create relationship data
            rd = RelationshipData()
            rd.ownerType = RelationshipDataElementType.FILENAME
            rd.ownerFileAbspath = bf.abspath
            rd.otherType = RelationshipDataElementType.FILENAME
            rd.otherFileAbspath = srcAbspath
            rd.rlnType = "GENERATED_FROM"

            # add it to pending relationships queue
            self.pendingRelationships.append(rd)

            # collect this source file's includes
            if self.cfg.analyzeIncludes and self.compilerPath:
                includes = self.collectIncludes(cfgTarget, pkg, bf, src)
                for inc in includes:
                    targetIncludesSet.add(inc)

        # make relationships for the overall included files,
        # avoiding duplicates for multiple source files including
        # the same headers
        targetIncludesList = list(targetIncludesSet)
        targetIncludesList.sort()
        for inc in targetIncludesList:
            # add it to pending source files queue
            self.pendingSources.append(inc)

            # create relationship data
            rd = RelationshipData()
            rd.ownerType = RelationshipDataElementType.FILENAME
            rd.ownerFileAbspath = bf.abspath
            rd.otherType = RelationshipDataElementType.FILENAME
            rd.otherFileAbspath = inc
            rd.rlnType = "GENERATED_FROM"

            # add it to pending relationships queue
            self.pendingRelationships.append(rd)

    # collect the include files corresponding to this source file
    # call with:
    #   1) ConfigTarget
    #   2) Package for this target
    #   3) build File for this target
    #   4) TargetSource entry for this source file
    # returns: sorted list of include files for this source file
    def collectIncludes(self, cfgTarget, pkg, bf, src):
        # get the right compile group for this source file
        if len(cfgTarget.target.compileGroups) < (src.compileGroupIndex + 1):
            log.dbg(f"    - {cfgTarget.target.name} has compileGroupIndex {src.compileGroupIndex} but only {len(cfgTarget.target.compileGroups)} found; skipping included files search")
            return []
        cg = cfgTarget.target.compileGroups[src.compileGroupIndex]

        # currently only doing C includes
        if cg.language != "C":
            log.dbg(f"    - {cfgTarget.target.name} has compile group language {cg.language} but currently only searching includes for C files; skipping included files search")
            return []

        srcAbspath = src.path
        if src.path[0] != "/":
            srcAbspath = os.path.join(self.cm.paths_source, src.path)
        return getCIncludes(self.compilerPath, srcAbspath, cg)

    # collect relationships for dependencies of this target Package
    # call with:
    #   1) all ConfigTargets from CodeModel
    #   2) this particular ConfigTarget
    #   3) Package for this Target
    def collectTargetDependencies(self, cfgTargets, cfgTarget, pkg):
        log.dbg(f"  - collecting target dependencies for {pkg.cfg.name}")

        # walk through target's dependencies
        for dep in cfgTarget.target.dependencies:
            # extract dep name from its id
            depFragments = dep.id.split(":")
            depName = depFragments[0]
            log.dbg(f"    - adding pending relationship for {depName}")

            # create relationship data between dependency packages
            rd = RelationshipData()
            rd.ownerType = RelationshipDataElementType.TARGETNAME
            rd.ownerTargetName = pkg.cfg.name
            rd.otherType = RelationshipDataElementType.TARGETNAME
            rd.otherTargetName = depName
            rd.rlnType = "HAS_PREREQUISITE"

            # add it to pending relationships queue
            self.pendingRelationships.append(rd)

            # if this is a target with any build artifacts (e.g. non-UTILITY),
            # also create STATIC_LINK relationship for dependency build files,
            # together with this Package's own target build file
            if len(cfgTarget.target.artifacts) == 0:
                continue

            # find the filename for the dependency's build product, using the
            # codemodel (since we might not have created this dependency's
            # Package or File yet)
            depAbspath = ""
            for ct in cfgTargets:
                if ct.name == depName:
                    # skip utility targets
                    if len(ct.target.artifacts) == 0:
                        continue
                    # all targets use the same relativeBaseDir, so this works
                    # even though pkg is the owner package
                    depAbspath = os.path.join(pkg.cfg.relativeBaseDir, ct.target.artifacts[0])
                    break
            if depAbspath == "":
                continue

            # create relationship data between build files
            rd = RelationshipData()
            rd.ownerType = RelationshipDataElementType.FILENAME
            rd.ownerFileAbspath = pkg.targetBuildFile.abspath
            rd.otherType = RelationshipDataElementType.FILENAME
            rd.otherFileAbspath = depAbspath
            rd.rlnType = "STATIC_LINK"

            # add it to pending relationships queue
            self.pendingRelationships.append(rd)

    # walk through pending sources and create corresponding files,
    # assigning them to the appropriate Document and Package
    def walkPendingSources(self):
        log.dbg(f"walking pending sources")

        # only one package in each doc; get it
        pkgZephyr = list(self.docZephyr.pkgs.values())[0]
        pkgApp = list(self.docApp.pkgs.values())[0]
        if self.cfg.includeSDK:
            pkgSDK = list(self.docSDK.pkgs.values())[0]

        for srcAbspath in self.pendingSources:
            # check whether we've already seen it
            srcDoc = self.allFileLinks.get(srcAbspath, None)
            srcPkg = None
            if srcDoc:
                log.dbg(f"  - {srcAbspath}: already seen, assigned to {srcDoc.cfg.name}")
                continue

            # not yet assigned; figure out where it goes
            pkgBuild = self.findBuildPackage(srcAbspath)
            pkgZephyr = self.findZephyrPackage(srcAbspath)

            if pkgBuild:
                log.dbg(f"  - {srcAbspath}: assigning to build document, package {pkgBuild.cfg.name}")
                srcDoc = self.docBuild
                srcPkg = pkgBuild
            elif self.cfg.includeSDK and os.path.commonpath([srcAbspath, pkgSDK.cfg.relativeBaseDir]) == pkgSDK.cfg.relativeBaseDir:
                log.dbg(f"  - {srcAbspath}: assigning to sdk document")
                srcDoc = self.docSDK
                srcPkg = pkgSDK
            elif os.path.commonpath([srcAbspath, pkgApp.cfg.relativeBaseDir]) == pkgApp.cfg.relativeBaseDir:
                log.dbg(f"  - {srcAbspath}: assigning to app document")
                srcDoc = self.docApp
                srcPkg = pkgApp
            elif pkgZephyr:
                log.dbg(f"  - {srcAbspath}: assigning to zephyr document")
                srcDoc = self.docZephyr
                srcPkg = pkgZephyr
            else:
                log.dbg(f"  - {srcAbspath}: can't determine which document should own; skipping")
                continue

            # create File and assign it to the Package and Document
            sf = File(srcDoc, srcPkg)
            sf.abspath = srcAbspath
            sf.relpath = os.path.relpath(srcAbspath, srcPkg.cfg.relativeBaseDir)
            filenameOnly = os.path.split(srcAbspath)[1]
            sf.spdxID = zspdx.spdxids.getUniqueFileID(filenameOnly, srcDoc.timesSeen)
            # don't fill hashes / licenses / rlns now, we'll do that after walking

            # add File to Package
            srcPkg.files[sf.spdxID] = sf

            # add file path link to Document and global links
            srcDoc.fileLinks[sf.abspath] = sf
            self.allFileLinks[sf.abspath] = srcDoc

    # figure out which Package contains the given file, if any
    # call with:
    #   1) absolute path for source filename being searched
    def findPackageFromSrcAbsPath(self, document, srcAbspath):
        # Multiple target Packages might "contain" the file path, if they
        # are nested. If so, the one with the longest path would be the
        # most deeply-nested target directory, so that's the one which
        # should get the file path.
        pkgLongestMatch = None
        for pkg in document.pkgs.values():
            if os.path.commonpath([srcAbspath, pkg.cfg.relativeBaseDir]) == pkg.cfg.relativeBaseDir:
                # the package does contain this file; is it the deepest?
                if pkgLongestMatch:
                    if len(pkg.cfg.relativeBaseDir) > len(pkgLongestMatch.cfg.relativeBaseDir):
                        pkgLongestMatch = pkg
                else:
                    # first package containing it, so assign it
                    pkgLongestMatch = pkg

        return pkgLongestMatch

    def findBuildPackage(self, srcAbspath):
        return self.findPackageFromSrcAbsPath(self.docBuild, srcAbspath)

    def findZephyrPackage(self, srcAbspath):
        return self.findPackageFromSrcAbsPath(self.docZephyr, srcAbspath)

    # walk through pending RelationshipData entries, create corresponding
    # Relationships, and assign them to the applicable Files / Packages
    def walkRelationships(self):
        for rlnData in self.pendingRelationships:
            rln = Relationship()
            # get left side of relationship data
            docA, spdxIDA, rlnsA = self.getRelationshipLeft(rlnData)
            if not docA or not spdxIDA:
                continue
            rln.refA = spdxIDA
            # get right side of relationship data
            spdxIDB = self.getRelationshipRight(rlnData, docA)
            if not spdxIDB:
                continue
            rln.refB = spdxIDB
            rln.rlnType = rlnData.rlnType
            rlnsA.append(rln)
            log.dbg(f"  - adding relationship to {docA.cfg.name}: {rln.refA} {rln.rlnType} {rln.refB}")

    # get owner (left side) document and SPDX ID of Relationship for given RelationshipData
    # returns: doc, spdxID, rlnsArray (for either Document, Package, or File, as applicable)
    def getRelationshipLeft(self, rlnData):
        if rlnData.ownerType == RelationshipDataElementType.FILENAME:
            # find the document for this file abspath, and then the specific file's ID
            ownerDoc = self.allFileLinks.get(rlnData.ownerFileAbspath, None)
            if not ownerDoc:
                log.dbg(f"  - searching for relationship, can't find document with file {rlnData.ownerFileAbspath}; skipping")
                return None, None, None
            sf = ownerDoc.fileLinks.get(rlnData.ownerFileAbspath, None)
            if not sf:
                log.dbg(f"  - searching for relationship for file {rlnData.ownerFileAbspath} points to document {ownerDoc.cfg.name} but file not found; skipping")
                return None, None, None
            # found it
            if not sf.spdxID:
                log.dbg(f"  - searching for relationship for file {rlnData.ownerFileAbspath} found file, but empty ID; skipping")
                return None, None, None
            return ownerDoc, sf.spdxID, sf.rlns
        elif rlnData.ownerType == RelationshipDataElementType.TARGETNAME:
            # find the document for this target name, and then the specific package's ID
            # for target names, must be docBuild
            ownerDoc = self.docBuild
            # walk through target Packages and check names
            for pkg in ownerDoc.pkgs.values():
                if pkg.cfg.name == rlnData.ownerTargetName:
                    if not pkg.cfg.spdxID:
                        log.dbg(f"  - searching for relationship for target {rlnData.ownerTargetName} found package, but empty ID; skipping")
                        return None, None, None
                    return ownerDoc, pkg.cfg.spdxID, pkg.rlns
            log.dbg(f"  - searching for relationship for target {rlnData.ownerTargetName}, target not found in build document; skipping")
            return None, None, None
        elif rlnData.ownerType == RelationshipDataElementType.DOCUMENT:
            # will always be SPDXRef-DOCUMENT
            return rlnData.ownerDocument, "SPDXRef-DOCUMENT", rlnData.ownerDocument.relationships
        else:
            log.dbg(f"  - unknown relationship type {rlnData.ownerType}; skipping")
            return None, None, None

    # get other (right side) SPDX ID of Relationship for given RelationshipData
    def getRelationshipRight(self, rlnData, docA):
        if rlnData.otherType == RelationshipDataElementType.FILENAME:
            # find the document for this file abspath, and then the specific file's ID
            otherDoc = self.allFileLinks.get(rlnData.otherFileAbspath, None)
            if not otherDoc:
                log.dbg(f"  - searching for relationship, can't find document with file {rlnData.otherFileAbspath}; skipping")
                return None
            bf = otherDoc.fileLinks.get(rlnData.otherFileAbspath, None)
            if not bf:
                log.dbg(f"  - searching for relationship for file {rlnData.otherFileAbspath} points to document {otherDoc.cfg.name} but file not found; skipping")
                return None
            # found it
            if not bf.spdxID:
                log.dbg(f"  - searching for relationship for file {rlnData.otherFileAbspath} found file, but empty ID; skipping")
                return None
            # figure out whether to append DocumentRef
            spdxIDB = bf.spdxID
            if otherDoc != docA:
                spdxIDB = otherDoc.cfg.docRefID + ":" + spdxIDB
                docA.externalDocuments.add(otherDoc)
            return spdxIDB
        elif rlnData.otherType == RelationshipDataElementType.TARGETNAME:
            # find the document for this target name, and then the specific package's ID
            # for target names, must be docBuild
            otherDoc = self.docBuild
            # walk through target Packages and check names
            for pkg in otherDoc.pkgs.values():
                if pkg.cfg.name == rlnData.otherTargetName:
                    if not pkg.cfg.spdxID:
                        log.dbg(f"  - searching for relationship for target {rlnData.otherTargetName} found package, but empty ID; skipping")
                        return None
                    spdxIDB = pkg.cfg.spdxID
                    if otherDoc != docA:
                        spdxIDB = otherDoc.cfg.docRefID + ":" + spdxIDB
                        docA.externalDocuments.add(otherDoc)
                    return spdxIDB
            log.dbg(f"  - searching for relationship for target {rlnData.otherTargetName}, target not found in build document; skipping")
            return None
        elif rlnData.otherType == RelationshipDataElementType.PACKAGEID:
            # will just be the package ID that was passed in
            return rlnData.otherPackageID
        else:
            log.dbg(f"  - unknown relationship type {rlnData.otherType}; skipping")
            return None
