"""
Factory to instantiate API clients
"""

from ossiq.adapters.api_clearlydefined import LicenseApiClearlyDefined
from ossiq.adapters.api_npm import PackageRegistryApiNpm
from ossiq.adapters.api_osv import CveApiOsv
from ossiq.adapters.api_pypi import PackageRegistryApiPypi
from ossiq.clients.clearlydefined import ClearlyDefinedSession
from ossiq.clients.github import GithubSession
from ossiq.clients.osv import OsvSession
from ossiq.domain.common import ProjectPackagesRegistry, RepositoryProvider
from ossiq.settings import Settings

from .api_github import SourceCodeProviderApiGithub
from .api_interfaces import (
    AbstractCveDatabaseApi,
    AbstractLicenseDatabaseApi,
    AbstractPackageRegistryApi,
    AbstractSourceCodeProviderApi,
)


def create_source_code_provider(provider_type: RepositoryProvider, settings: Settings) -> AbstractSourceCodeProviderApi:
    """
    Return source code provider (like Github) using factory and respective type
    """
    if provider_type == RepositoryProvider.PROVIDER_GITHUB:
        return SourceCodeProviderApiGithub(GithubSession(settings.github_token))
    else:
        raise ValueError(f"Unknown source code provider type: {provider_type}")


def create_package_registry_api(
    package_registry: ProjectPackagesRegistry, settings: Settings
) -> AbstractPackageRegistryApi:
    """
    Create instance of a specific ecosystem's package registry API
    """

    if package_registry == ProjectPackagesRegistry.NPM:
        return PackageRegistryApiNpm(settings)
    elif package_registry == ProjectPackagesRegistry.PYPI:
        return PackageRegistryApiPypi(settings)
    else:
        raise ValueError(f"Unknown package registry: {package_registry}")


def create_cve_database(settings: Settings) -> AbstractCveDatabaseApi:
    """
    Return CVE database (like osv.dev). The purpose is little different from
    Source Code Provider or Packages Registry/Ecosystem: there might be
    more than one CSV database. For externel clients it should look like a
    single database instance still.
    """
    return CveApiOsv(
        OsvSession(
            cache_destination=settings.cache_destination,
            cache_ttl_hours=settings.cache_ttl,
        )
    )


def create_license_database(settings: Settings) -> AbstractLicenseDatabaseApi:
    """
    Return license database (ClearlyDefined) for normalized SPDX license lookups.
    """
    return LicenseApiClearlyDefined(
        ClearlyDefinedSession(
            cache_destination=settings.cache_destination,
            cache_ttl_hours=settings.cache_ttl,
        )
    )
