package com.blackduck.integration.detectable.factory;

import java.io.File;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import com.blackduck.integration.detectable.detectable.executable.resolver.*;
import com.blackduck.integration.detectable.detectables.cargo.*;
import com.blackduck.integration.detectable.detectables.cargo.transform.CargoDependencyGraphTransformer;
import com.blackduck.integration.detectable.detectables.pip.inspector.parser.PipInspectorTomlParser;
import com.blackduck.integration.detectable.detectables.uv.UVDetectorOptions;
import com.blackduck.integration.detectable.detectables.uv.buildexe.UVBuildDetectable;
import com.blackduck.integration.detectable.detectables.uv.buildexe.UVBuildExtractor;
import com.blackduck.integration.detectable.detectables.uv.lockfile.UVLockFileDetectable;
import com.blackduck.integration.detectable.detectables.uv.lockfile.UVLockfileExtractor;
import com.blackduck.integration.detectable.detectables.uv.transform.UVLockParser;
import com.blackduck.integration.detectable.detectables.uv.transform.UVTreeDependencyGraphTransformer;
import org.xml.sax.SAXException;

import com.google.gson.Gson;
import com.blackduck.integration.bdio.BdioTransformer;
import com.blackduck.integration.bdio.model.externalid.ExternalIdFactory;
import com.blackduck.integration.common.util.finder.FileFinder;
import com.blackduck.integration.common.util.parse.CommandParser;
import com.blackduck.integration.detectable.DetectableEnvironment;
import com.blackduck.integration.detectable.detectable.executable.DetectableExecutableRunner;
import com.blackduck.integration.detectable.detectable.inspector.GradleInspectorResolver;
import com.blackduck.integration.detectable.detectable.inspector.PipInspectorResolver;
import com.blackduck.integration.detectable.detectable.inspector.ProjectInspectorResolver;
import com.blackduck.integration.detectable.detectable.inspector.nuget.NugetInspectorResolver;
import com.blackduck.integration.detectable.detectables.bazel.BazelDetectable;
import com.blackduck.integration.detectable.detectables.bazel.BazelDetectableOptions;
import com.blackduck.integration.detectable.detectables.bazel.BazelExtractor;
import com.blackduck.integration.detectable.detectables.bazel.BazelProjectNameGenerator;
import com.blackduck.integration.detectable.detectables.bazel.BazelWorkspaceFileParser;
import com.blackduck.integration.detectable.detectables.bazel.pipeline.WorkspaceRuleChooser;
import com.blackduck.integration.detectable.detectables.bazel.pipeline.step.BazelVariableSubstitutor;
import com.blackduck.integration.detectable.detectables.bazel.pipeline.step.HaskellCabalLibraryJsonProtoParser;
import com.blackduck.integration.detectable.detectables.bitbake.BitbakeDetectable;
import com.blackduck.integration.detectable.detectables.bitbake.BitbakeDetectableOptions;
import com.blackduck.integration.detectable.detectables.bitbake.BitbakeExtractor;
import com.blackduck.integration.detectable.detectables.bitbake.collect.BitbakeCommandRunner;
import com.blackduck.integration.detectable.detectables.bitbake.collect.BuildFileFinder;
import com.blackduck.integration.detectable.detectables.bitbake.parse.BitbakeEnvironmentParser;
import com.blackduck.integration.detectable.detectables.bitbake.parse.BitbakeRecipesParser;
import com.blackduck.integration.detectable.detectables.bitbake.parse.GraphNodeLabelParser;
import com.blackduck.integration.detectable.detectables.bitbake.parse.LicenseManifestParser;
import com.blackduck.integration.detectable.detectables.bitbake.parse.PwdOutputParser;
import com.blackduck.integration.detectable.detectables.bitbake.transform.BitbakeDependencyGraphTransformer;
import com.blackduck.integration.detectable.detectables.bitbake.transform.BitbakeGraphTransformer;
import com.blackduck.integration.detectable.detectables.cargo.parse.CargoDependencyLineParser;
import com.blackduck.integration.detectable.detectables.cargo.parse.CargoTomlParser;
import com.blackduck.integration.detectable.detectables.cargo.transform.CargoLockPackageDataTransformer;
import com.blackduck.integration.detectable.detectables.cargo.transform.CargoLockPackageTransformer;
import com.blackduck.integration.detectable.detectables.carthage.CarthageExtractor;
import com.blackduck.integration.detectable.detectables.carthage.CarthageLockDetectable;
import com.blackduck.integration.detectable.detectables.carthage.parse.CartfileResolvedParser;
import com.blackduck.integration.detectable.detectables.carthage.transform.CarthageDeclarationTransformer;
import com.blackduck.integration.detectable.detectables.clang.ClangDetectable;
import com.blackduck.integration.detectable.detectables.clang.ClangDetectableOptions;
import com.blackduck.integration.detectable.detectables.clang.ClangExtractor;
import com.blackduck.integration.detectable.detectables.clang.ForgeChooser;
import com.blackduck.integration.detectable.detectables.clang.LinuxDistroToForgeMapper;
import com.blackduck.integration.detectable.detectables.clang.compilecommand.CompileCommandDatabaseParser;
import com.blackduck.integration.detectable.detectables.clang.compilecommand.CompileCommandParser;
import com.blackduck.integration.detectable.detectables.clang.dependencyfile.ClangPackageDetailsTransformer;
import com.blackduck.integration.detectable.detectables.clang.dependencyfile.DependencyFileDetailGenerator;
import com.blackduck.integration.detectable.detectables.clang.dependencyfile.DependencyListFileParser;
import com.blackduck.integration.detectable.detectables.clang.dependencyfile.FilePathGenerator;
import com.blackduck.integration.detectable.detectables.clang.linux.LinuxDistro;
import com.blackduck.integration.detectable.detectables.clang.packagemanager.ClangPackageManagerFactory;
import com.blackduck.integration.detectable.detectables.clang.packagemanager.ClangPackageManagerInfoFactory;
import com.blackduck.integration.detectable.detectables.clang.packagemanager.ClangPackageManagerRunner;
import com.blackduck.integration.detectable.detectables.cocoapods.PodlockDetectable;
import com.blackduck.integration.detectable.detectables.cocoapods.PodlockExtractor;
import com.blackduck.integration.detectable.detectables.cocoapods.parser.PodlockParser;
import com.blackduck.integration.detectable.detectables.conan.ConanCodeLocationGenerator;
import com.blackduck.integration.detectable.detectables.conan.cli.Conan1CliDetectable;
import com.blackduck.integration.detectable.detectables.conan.cli.Conan2CliDetectable;
import com.blackduck.integration.detectable.detectables.conan.cli.ConanCliExtractor;
import com.blackduck.integration.detectable.detectables.conan.cli.ConanResolver;
import com.blackduck.integration.detectable.detectables.conan.cli.config.ConanCliOptions;
import com.blackduck.integration.detectable.detectables.conan.cli.parser.conan1.ConanInfoLineAnalyzer;
import com.blackduck.integration.detectable.detectables.conan.cli.parser.conan1.ConanInfoNodeParser;
import com.blackduck.integration.detectable.detectables.conan.cli.parser.conan1.ConanInfoParser;
import com.blackduck.integration.detectable.detectables.conan.cli.parser.conan1.element.NodeElementParser;
import com.blackduck.integration.detectable.detectables.conan.cli.parser.conan2.ConanGraphInfoParser;
import com.blackduck.integration.detectable.detectables.conan.cli.process.ConanCommandRunner;
import com.blackduck.integration.detectable.detectables.conan.lockfile.ConanLockfileDetectable;
import com.blackduck.integration.detectable.detectables.conan.lockfile.ConanLockfileExtractor;
import com.blackduck.integration.detectable.detectables.conan.lockfile.ConanLockfileExtractorOptions;
import com.blackduck.integration.detectable.detectables.conan.lockfile.parser.ConanLockfileParser;
import com.blackduck.integration.detectable.detectables.conda.CondaCliDetectable;
import com.blackduck.integration.detectable.detectables.conda.CondaCliDetectableOptions;
import com.blackduck.integration.detectable.detectables.conda.CondaCliExtractor;
import com.blackduck.integration.detectable.detectables.conda.parser.CondaDependencyCreator;
import com.blackduck.integration.detectable.detectables.conda.parser.CondaListParser;
import com.blackduck.integration.detectable.detectables.cpan.CpanCliDetectable;
import com.blackduck.integration.detectable.detectables.cpan.CpanCliExtractor;
import com.blackduck.integration.detectable.detectables.cpan.parse.CpanListParser;
import com.blackduck.integration.detectable.detectables.cran.PackratLockDetectable;
import com.blackduck.integration.detectable.detectables.cran.PackratLockExtractor;
import com.blackduck.integration.detectable.detectables.cran.parse.PackratDescriptionFileParser;
import com.blackduck.integration.detectable.detectables.cran.parse.PackratLockFileParser;
import com.blackduck.integration.detectable.detectables.dart.PubSpecYamlNameVersionParser;
import com.blackduck.integration.detectable.detectables.dart.pubdep.DartPubDepDetectable;
import com.blackduck.integration.detectable.detectables.dart.pubdep.DartPubDepsDetectableOptions;
import com.blackduck.integration.detectable.detectables.dart.pubdep.PubDepsExtractor;
import com.blackduck.integration.detectable.detectables.dart.pubdep.PubDepsParser;
import com.blackduck.integration.detectable.detectables.dart.pubspec.DartPubSpecLockDetectable;
import com.blackduck.integration.detectable.detectables.dart.pubspec.PubSpecExtractor;
import com.blackduck.integration.detectable.detectables.dart.pubspec.PubSpecLockParser;
import com.blackduck.integration.detectable.detectables.docker.DockerDetectable;
import com.blackduck.integration.detectable.detectables.docker.DockerDetectableOptions;
import com.blackduck.integration.detectable.detectables.docker.DockerExtractor;
import com.blackduck.integration.detectable.detectables.docker.DockerInspectorResolver;
import com.blackduck.integration.detectable.detectables.docker.ImageIdentifierGenerator;
import com.blackduck.integration.detectable.detectables.docker.parser.DockerInspectorResultsFileParser;
import com.blackduck.integration.detectable.detectables.git.GitCliDetectable;
import com.blackduck.integration.detectable.detectables.git.GitParseDetectable;
import com.blackduck.integration.detectable.detectables.git.GitUrlParser;
import com.blackduck.integration.detectable.detectables.git.cli.GitCliExtractor;
import com.blackduck.integration.detectable.detectables.git.cli.GitCommandRunner;
import com.blackduck.integration.detectable.detectables.git.parsing.GitParseExtractor;
import com.blackduck.integration.detectable.detectables.git.parsing.parse.GitConfigNameVersionTransformer;
import com.blackduck.integration.detectable.detectables.git.parsing.parse.GitConfigNodeTransformer;
import com.blackduck.integration.detectable.detectables.git.parsing.parse.GitFileParser;
import com.blackduck.integration.detectable.detectables.go.godep.GoDepExtractor;
import com.blackduck.integration.detectable.detectables.go.godep.GoDepLockDetectable;
import com.blackduck.integration.detectable.detectables.go.godep.parse.GoLockParser;
import com.blackduck.integration.detectable.detectables.go.gogradle.GoGradleDetectable;
import com.blackduck.integration.detectable.detectables.go.gogradle.GoGradleExtractor;
import com.blackduck.integration.detectable.detectables.go.gogradle.GoGradleLockParser;
import com.blackduck.integration.detectable.detectables.go.gomod.GoModCliDetectable;
import com.blackduck.integration.detectable.detectables.go.gomod.GoModCliDetectableOptions;
import com.blackduck.integration.detectable.detectables.go.gomod.GoModCliExtractor;
import com.blackduck.integration.detectable.detectables.go.gomod.GoModCommandRunner;
import com.blackduck.integration.detectable.detectables.go.gomod.parse.GoGraphParser;
import com.blackduck.integration.detectable.detectables.go.gomod.parse.GoListParser;
import com.blackduck.integration.detectable.detectables.go.gomod.parse.GoModWhyParser;
import com.blackduck.integration.detectable.detectables.go.gomod.parse.GoVersionParser;
import com.blackduck.integration.detectable.detectables.go.gomod.process.GoModGraphGenerator;
import com.blackduck.integration.detectable.detectables.go.gomodfile.GoModFileDetectable;
import com.blackduck.integration.detectable.detectables.go.gomodfile.GoModFileDetectableOptions;
import com.blackduck.integration.detectable.detectables.go.gomodfile.GoModFileExtractor;
import com.blackduck.integration.detectable.detectables.go.vendor.GoVendorDetectable;
import com.blackduck.integration.detectable.detectables.go.vendor.GoVendorExtractor;
import com.blackduck.integration.detectable.detectables.go.vendr.GoVndrDetectable;
import com.blackduck.integration.detectable.detectables.go.vendr.GoVndrExtractor;
import com.blackduck.integration.detectable.detectables.gradle.inspection.GradleInspectorDetectable;
import com.blackduck.integration.detectable.detectables.gradle.inspection.GradleInspectorExtractor;
import com.blackduck.integration.detectable.detectables.gradle.inspection.GradleInspectorOptions;
import com.blackduck.integration.detectable.detectables.gradle.inspection.GradleRunner;
import com.blackduck.integration.detectable.detectables.gradle.inspection.parse.GradleReportParser;
import com.blackduck.integration.detectable.detectables.gradle.inspection.parse.GradleReportTransformer;
import com.blackduck.integration.detectable.detectables.gradle.inspection.parse.GradleRootMetadataParser;
import com.blackduck.integration.detectable.detectables.gradle.parsing.GradleProjectInspectorDetectable;
import com.blackduck.integration.detectable.detectables.ivy.IvyParseDetectable;
import com.blackduck.integration.detectable.detectables.ivy.IvyParseExtractor;
import com.blackduck.integration.detectable.detectables.ivy.parse.IvyProjectNameParser;
import com.blackduck.integration.detectable.detectables.lerna.LernaDetectable;
import com.blackduck.integration.detectable.detectables.lerna.LernaExtractor;
import com.blackduck.integration.detectable.detectables.lerna.LernaOptions;
import com.blackduck.integration.detectable.detectables.lerna.LernaPackageDiscoverer;
import com.blackduck.integration.detectable.detectables.lerna.LernaPackager;
import com.blackduck.integration.detectable.detectables.maven.cli.MavenCliExtractor;
import com.blackduck.integration.detectable.detectables.maven.cli.MavenCliExtractorOptions;
import com.blackduck.integration.detectable.detectables.maven.cli.MavenCodeLocationPackager;
import com.blackduck.integration.detectable.detectables.maven.cli.MavenPomDetectable;
import com.blackduck.integration.detectable.detectables.maven.cli.MavenPomWrapperDetectable;
import com.blackduck.integration.detectable.detectables.maven.parsing.MavenProjectInspectorDetectable;
import com.blackduck.integration.detectable.detectables.npm.cli.NpmCliDetectable;
import com.blackduck.integration.detectable.detectables.npm.cli.NpmCliExtractor;
import com.blackduck.integration.detectable.detectables.npm.cli.NpmCliExtractorOptions;
import com.blackduck.integration.detectable.detectables.npm.cli.parse.NpmCliParser;
import com.blackduck.integration.detectable.detectables.npm.lockfile.NpmLockfileExtractor;
import com.blackduck.integration.detectable.detectables.npm.lockfile.NpmLockfileOptions;
import com.blackduck.integration.detectable.detectables.npm.lockfile.NpmPackageLockDetectable;
import com.blackduck.integration.detectable.detectables.npm.lockfile.NpmShrinkwrapDetectable;
import com.blackduck.integration.detectable.detectables.npm.lockfile.parse.NpmLockFileProjectIdTransformer;
import com.blackduck.integration.detectable.detectables.npm.lockfile.parse.NpmLockfileGraphTransformer;
import com.blackduck.integration.detectable.detectables.npm.lockfile.parse.NpmLockfilePackager;
import com.blackduck.integration.detectable.detectables.npm.packagejson.NpmPackageJsonParseDetectable;
import com.blackduck.integration.detectable.detectables.npm.packagejson.NpmPackageJsonParseDetectableOptions;
import com.blackduck.integration.detectable.detectables.npm.packagejson.PackageJsonExtractor;
import com.blackduck.integration.detectable.detectables.nuget.NugetInspectorExtractor;
import com.blackduck.integration.detectable.detectables.nuget.NugetInspectorOptions;
import com.blackduck.integration.detectable.detectables.nuget.NugetProjectDetectable;
import com.blackduck.integration.detectable.detectables.nuget.NugetProjectInspectorDetectable;
import com.blackduck.integration.detectable.detectables.nuget.NugetSolutionDetectable;
import com.blackduck.integration.detectable.detectables.nuget.parse.NugetInspectorParser;
import com.blackduck.integration.detectable.detectables.packagist.ComposerLockDetectable;
import com.blackduck.integration.detectable.detectables.packagist.ComposerLockDetectableOptions;
import com.blackduck.integration.detectable.detectables.packagist.ComposerLockExtractor;
import com.blackduck.integration.detectable.detectables.packagist.parse.PackagistParser;
import com.blackduck.integration.detectable.detectables.pear.PearCliDetectable;
import com.blackduck.integration.detectable.detectables.pear.PearCliDetectableOptions;
import com.blackduck.integration.detectable.detectables.pear.PearCliExtractor;
import com.blackduck.integration.detectable.detectables.pear.parse.PearListParser;
import com.blackduck.integration.detectable.detectables.pear.parse.PearPackageDependenciesParser;
import com.blackduck.integration.detectable.detectables.pear.parse.PearPackageXmlParser;
import com.blackduck.integration.detectable.detectables.pear.transform.PearDependencyGraphTransformer;
import com.blackduck.integration.detectable.detectables.pip.inspector.PipInspectorDetectable;
import com.blackduck.integration.detectable.detectables.pip.inspector.PipInspectorDetectableOptions;
import com.blackduck.integration.detectable.detectables.pip.inspector.PipInspectorExtractor;
import com.blackduck.integration.detectable.detectables.pip.inspector.parser.PipInspectorTreeParser;
import com.blackduck.integration.detectable.detectables.pip.parser.RequirementsFileDependencyTransformer;
import com.blackduck.integration.detectable.detectables.pip.parser.RequirementsFileDetectable;
import com.blackduck.integration.detectable.detectables.pip.parser.RequirementsFileDetectableOptions;
import com.blackduck.integration.detectable.detectables.pip.parser.RequirementsFileExtractor;
import com.blackduck.integration.detectable.detectables.pipenv.tbuild.PipenvDetectable;
import com.blackduck.integration.detectable.detectables.pipenv.tbuild.PipenvDetectableOptions;
import com.blackduck.integration.detectable.detectables.pipenv.tbuild.PipenvExtractor;
import com.blackduck.integration.detectable.detectables.pipenv.tbuild.parser.PipEnvJsonGraphParser;
import com.blackduck.integration.detectable.detectables.pipenv.tbuild.parser.PipenvFreezeParser;
import com.blackduck.integration.detectable.detectables.pipenv.tbuild.parser.PipenvTransformer;
import com.blackduck.integration.detectable.detectables.pipenv.parse.PipfileLockDependencyTransformer;
import com.blackduck.integration.detectable.detectables.pipenv.parse.PipfileLockDependencyVersionParser;
import com.blackduck.integration.detectable.detectables.pipenv.parse.PipfileLockDetectable;
import com.blackduck.integration.detectable.detectables.pipenv.parse.PipfileLockDetectableOptions;
import com.blackduck.integration.detectable.detectables.pipenv.parse.PipfileLockExtractor;
import com.blackduck.integration.detectable.detectables.pipenv.parse.PipfileLockTransformer;
import com.blackduck.integration.detectable.detectables.pnpm.lockfile.PnpmLockDetectable;
import com.blackduck.integration.detectable.detectables.pnpm.lockfile.PnpmLockExtractor;
import com.blackduck.integration.detectable.detectables.pnpm.lockfile.PnpmLockOptions;
import com.blackduck.integration.detectable.detectables.pnpm.lockfile.process.PnpmLockYamlParserInitial;
import com.blackduck.integration.detectable.detectables.poetry.PoetryDetectable;
import com.blackduck.integration.detectable.detectables.poetry.PoetryExtractor;
import com.blackduck.integration.detectable.detectables.poetry.PoetryOptions;
import com.blackduck.integration.detectable.detectables.poetry.parser.PoetryLockParser;
import com.blackduck.integration.detectable.detectables.poetry.parser.ToolPoetrySectionParser;
import com.blackduck.integration.detectable.detectables.projectinspector.ProjectInspectorExtractor;
import com.blackduck.integration.detectable.detectables.projectinspector.ProjectInspectorOptions;
import com.blackduck.integration.detectable.detectables.projectinspector.ProjectInspectorParser;
import com.blackduck.integration.detectable.detectables.rebar.RebarDetectable;
import com.blackduck.integration.detectable.detectables.rebar.RebarExtractor;
import com.blackduck.integration.detectable.detectables.rebar.parse.Rebar3TreeParser;
import com.blackduck.integration.detectable.detectables.rubygems.gemlock.GemlockDetectable;
import com.blackduck.integration.detectable.detectables.rubygems.gemlock.GemlockExtractor;
import com.blackduck.integration.detectable.detectables.rubygems.gemspec.GemspecParseDetectable;
import com.blackduck.integration.detectable.detectables.rubygems.gemspec.GemspecParseDetectableOptions;
import com.blackduck.integration.detectable.detectables.rubygems.gemspec.GemspecParseExtractor;
import com.blackduck.integration.detectable.detectables.rubygems.gemspec.parse.GemspecLineParser;
import com.blackduck.integration.detectable.detectables.rubygems.gemspec.parse.GemspecParser;
import com.blackduck.integration.detectable.detectables.sbt.SbtDetectable;
import com.blackduck.integration.detectable.detectables.sbt.SbtDetectableOptions;
import com.blackduck.integration.detectable.detectables.sbt.dot.SbtCommandArgumentGenerator;
import com.blackduck.integration.detectable.detectables.sbt.dot.SbtDotExtractor;
import com.blackduck.integration.detectable.detectables.sbt.dot.SbtDotGraphNodeParser;
import com.blackduck.integration.detectable.detectables.sbt.dot.SbtDotOutputParser;
import com.blackduck.integration.detectable.detectables.sbt.dot.SbtGraphParserTransformer;
import com.blackduck.integration.detectable.detectables.sbt.dot.SbtPluginFinder;
import com.blackduck.integration.detectable.detectables.sbt.dot.SbtRootNodeFinder;
import com.blackduck.integration.detectable.detectables.setuptools.SetupToolsExtractor;
import com.blackduck.integration.detectable.detectables.setuptools.tbuild.SetupToolsBuildDetectable;
import com.blackduck.integration.detectable.detectables.setuptools.buildless.SetupToolsBuildlessDetectable;
import com.blackduck.integration.detectable.detectables.setuptools.transform.SetupToolsGraphTransformer;
import com.blackduck.integration.detectable.detectables.swift.cli.SwiftCliDetectable;
import com.blackduck.integration.detectable.detectables.swift.cli.SwiftCliParser;
import com.blackduck.integration.detectable.detectables.swift.cli.SwiftExtractor;
import com.blackduck.integration.detectable.detectables.swift.cli.SwiftPackageTransformer;
import com.blackduck.integration.detectable.detectables.swift.lock.PackageResolvedExtractor;
import com.blackduck.integration.detectable.detectables.swift.lock.SwiftPackageResolvedDetectable;
import com.blackduck.integration.detectable.detectables.swift.lock.parse.PackageResolvedDataChecker;
import com.blackduck.integration.detectable.detectables.swift.lock.parse.PackageResolvedFormatChecker;
import com.blackduck.integration.detectable.detectables.swift.lock.parse.PackageResolvedFormatParser;
import com.blackduck.integration.detectable.detectables.swift.lock.parse.PackageResolvedParser;
import com.blackduck.integration.detectable.detectables.swift.lock.transform.PackageResolvedTransformer;
import com.blackduck.integration.detectable.detectables.xcode.XcodeProjectDetectable;
import com.blackduck.integration.detectable.detectables.xcode.XcodeWorkspaceDetectable;
import com.blackduck.integration.detectable.detectables.xcode.XcodeWorkspaceExtractor;
import com.blackduck.integration.detectable.detectables.xcode.parse.XcodeWorkspaceFormatChecker;
import com.blackduck.integration.detectable.detectables.xcode.parse.XcodeWorkspaceParser;
import com.blackduck.integration.detectable.detectables.yarn.YarnLockDetectable;
import com.blackduck.integration.detectable.detectables.yarn.YarnLockExtractor;
import com.blackduck.integration.detectable.detectables.yarn.YarnLockOptions;
import com.blackduck.integration.detectable.detectables.yarn.YarnPackager;
import com.blackduck.integration.detectable.detectables.yarn.YarnTransformer;
import com.blackduck.integration.detectable.detectables.yarn.packagejson.PackageJsonFiles;
import com.blackduck.integration.detectable.detectables.yarn.packagejson.PackageJsonReader;
import com.blackduck.integration.detectable.detectables.yarn.parse.YarnLockLineAnalyzer;
import com.blackduck.integration.detectable.detectables.yarn.parse.YarnLockParser;
import com.blackduck.integration.detectable.detectables.yarn.parse.entry.YarnLockEntryParser;
import com.blackduck.integration.detectable.detectables.yarn.parse.entry.section.YarnLockDependencySpecParser;
import com.blackduck.integration.detectable.detectables.yarn.parse.entry.section.YarnLockEntrySectionParserSet;
import com.blackduck.integration.detectable.python.util.PythonDependencyTransformer;
import com.blackduck.integration.detectable.detectables.opam.buildexe.OpamBuildDetectable;
import com.blackduck.integration.detectable.detectables.opam.buildexe.OpamBuildExtractor;
import com.blackduck.integration.detectable.detectables.opam.buildexe.parse.OpamTreeParser;
import com.blackduck.integration.detectable.detectables.opam.lockfile.OpamLockFileDetectable;
import com.blackduck.integration.detectable.detectables.opam.lockfile.OpamLockFileExtractor;
import com.blackduck.integration.detectable.detectables.opam.transform.OpamGraphTransformer;
import com.blackduck.integration.detectable.util.ToolVersionLogger;

/*
 Entry point for creating detectables using most
 */
public class DetectableFactory {

    private final FileFinder fileFinder;
    private final DetectableExecutableRunner executableRunner;
    private final ExternalIdFactory externalIdFactory;
    private final Gson gson;
    private final ToolVersionLogger toolVersionLogger;

    public DetectableFactory(FileFinder fileFinder, DetectableExecutableRunner executableRunner, ExternalIdFactory externalIdFactory, Gson gson) {
        this.fileFinder = fileFinder;
        this.executableRunner = executableRunner;
        this.externalIdFactory = externalIdFactory;
        this.gson = gson;
        this.toolVersionLogger = new ToolVersionLogger(executableRunner);
    }

    //#region Detectables

    //Detectables
    //Should be scoped to Prototype so a new Detectable is created every time one is needed.
    //Should only be accessed through the DetectableFactory.

    public DockerDetectable createDockerDetectable(
        DetectableEnvironment environment,
        DockerDetectableOptions dockerDetectableOptions,
        DockerInspectorResolver dockerInspectorResolver,
        JavaResolver javaResolver,
        DockerResolver dockerResolver
    ) {
        return new DockerDetectable(environment, dockerInspectorResolver, javaResolver, dockerResolver, dockerExtractor(), dockerDetectableOptions);
    }

    public BazelDetectable createBazelDetectable(DetectableEnvironment environment, BazelDetectableOptions bazelDetectableOptions, BazelResolver bazelResolver) {
        return new BazelDetectable(environment, fileFinder, bazelExtractor(bazelDetectableOptions), bazelResolver, bazelDetectableOptions.getTargetName().orElse(null));
    }

    public BitbakeDetectable createBitbakeDetectable(DetectableEnvironment environment, BitbakeDetectableOptions bitbakeDetectableOptions, BashResolver bashResolver) {
        BitbakeExtractor bitbakeExtractor = new BitbakeExtractor(
            toolVersionLogger,
            new BitbakeCommandRunner(executableRunner, bitbakeDetectableOptions.getSourceArguments()),
            new BuildFileFinder(fileFinder, bitbakeDetectableOptions.isFollowSymLinks(), bitbakeDetectableOptions.getSearchDepth()),
            new PwdOutputParser(),
            new BitbakeEnvironmentParser(),
            new BitbakeRecipesParser(),
            new LicenseManifestParser(),
            new BitbakeGraphTransformer(new GraphNodeLabelParser()),
            new BitbakeDependencyGraphTransformer(bitbakeDetectableOptions.getDependencyTypeFilter()),
            bitbakeDetectableOptions.getPackageNames(),
            bitbakeDetectableOptions.getDependencyTypeFilter()
        );
        return new BitbakeDetectable(environment, fileFinder, bitbakeDetectableOptions, bitbakeExtractor, bashResolver);
    }

    public CargoLockDetectable createCargoLockfileDetectable(DetectableEnvironment environment) {
        return createCargoLockfileDetectable(environment, null);
    }

    public CargoLockDetectable createCargoLockfileDetectable(DetectableEnvironment environment, CargoDetectableOptions cargoDetectableOptions) {
        CargoTomlParser cargoTomlParser = new CargoTomlParser();
        CargoDependencyLineParser cargoDependencyLineParser = new CargoDependencyLineParser();
        CargoLockPackageDataTransformer cargoLockPackageDataTransformer = new CargoLockPackageDataTransformer(cargoDependencyLineParser);
        CargoLockPackageTransformer cargoLockPackageTransformer = new CargoLockPackageTransformer();
        CargoLockfileExtractor cargoLockfileExtractor = new CargoLockfileExtractor(cargoTomlParser, cargoLockPackageDataTransformer, cargoLockPackageTransformer);
        return new CargoLockDetectable(environment, fileFinder, cargoLockfileExtractor, cargoDetectableOptions);
    }

    public CargoCliDetectable createCargoCliDetectable(DetectableEnvironment environment, CargoResolver cargoResolver, CargoDetectableOptions cargoDetectableOptions) {
        CargoDependencyGraphTransformer cargoDependencyTransformer= new CargoDependencyGraphTransformer(externalIdFactory);
        CargoTomlParser cargoTomlParser = new CargoTomlParser();
        CargoCliExtractor cargoCliExtractor = new CargoCliExtractor(executableRunner, cargoDependencyTransformer, cargoTomlParser);
        return new CargoCliDetectable(environment, fileFinder, cargoResolver, cargoCliExtractor, executableRunner, cargoDetectableOptions);
    }



    public CarthageLockDetectable createCarthageDetectable(DetectableEnvironment environment) {
        CartfileResolvedParser cartfileResolvedParser = new CartfileResolvedParser();
        CarthageDeclarationTransformer carthageDeclarationTransformer = new CarthageDeclarationTransformer();
        CarthageExtractor carthageExtractor = new CarthageExtractor(cartfileResolvedParser, carthageDeclarationTransformer);
        return new CarthageLockDetectable(environment, fileFinder, carthageExtractor);
    }

    public ClangDetectable createClangDetectable(DetectableEnvironment environment, ClangDetectableOptions clangDetectableOptions) {
        return new ClangDetectable(
            environment,
            executableRunner,
            fileFinder,
            clangPackageManagerFactory().createPackageManagers(),
            clangExtractor(),
            clangDetectableOptions,
            clangPackageManagerRunner()
        );
    }

    public ComposerLockDetectable createComposerDetectable(DetectableEnvironment environment, ComposerLockDetectableOptions composerLockDetectableOptions) {
        PackagistParser packagistParser = new PackagistParser(externalIdFactory, composerLockDetectableOptions.getDependencyTypeFilter());
        ComposerLockExtractor composerLockExtractor = new ComposerLockExtractor(packagistParser);
        return new ComposerLockDetectable(environment, fileFinder, composerLockExtractor);
    }

    public CondaCliDetectable createCondaCliDetectable(DetectableEnvironment environment, CondaResolver condaResolver, CondaCliDetectableOptions condaCliDetectableOptions) {
        return new CondaCliDetectable(environment, fileFinder, condaResolver, condaCliExtractor(), condaCliDetectableOptions);
    }

    public CpanCliDetectable createCpanCliDetectable(DetectableEnvironment environment, CpanResolver cpanResolver, CpanmResolver cpanmResolver) {
        return new CpanCliDetectable(environment, fileFinder, cpanResolver, cpanmResolver, cpanCliExtractor());
    }

    public DartPubSpecLockDetectable createDartPubSpecLockDetectable(DetectableEnvironment environment) {
        PubSpecLockParser pubSpecLockParser = new PubSpecLockParser();
        PubSpecYamlNameVersionParser pubSpecYamlNameVersionParser = new PubSpecYamlNameVersionParser();
