# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration

imports:
    - { resource: parameters.yaml }

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        bind:
            bool $demo_mode: '%partdb.demo_mode%'
            bool $gdpr_compliance: '%partdb.gdpr_compliance%'
            bool $kernel_debug_enabled: '%kernel.debug%'
            string $kernel_cache_dir: '%kernel.cache_dir%'
            string $partdb_title: '%partdb.title%'
            string $base_currency: '%partdb.default_currency%'

    _instanceof:
        App\Services\LabelSystem\PlaceholderProviders\PlaceholderProviderInterface:
            tags: ['app.label_placeholder_provider']

        App\Services\InfoProviderSystem\Providers\InfoProviderInterface:
            tags: ['app.info_provider']

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/'
        exclude:
            - '../src/DependencyInjection/'
            - '../src/Entity/'
            - '../src/Kernel.php'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']

    ####################################################################################################################
    # Alias definitions
    ####################################################################################################################
    Swap\Swap:
        alias: 'florianv_swap.swap'

    Doctrine\Migrations\DependencyFactory:
        alias: 'doctrine.migrations.dependency_factory'


    ####################################################################################################################
    # Email
    ####################################################################################################################

    App\EventSubscriber\SetMailFromSubscriber:
        tags: ['kernel.event_subscriber']
        arguments:
            $email: '%partdb.mail.sender_email%'
            $name: '%partdb.mail.sender_name%'

    ####################################################################################################################
    # Log System
    ####################################################################################################################

    App\Services\LogSystem\EventLogger:
        arguments:
            # By default only log events which has minimum info level (debug levels are not logged)
            # 7 is lowest level (debug), 0 highest (emergency
            $minimum_log_level: 6
            # Event classes specified here are not saved to DB
            $blacklist: []
            # Only the event classes specified here are saved to DB (set to []) to log all events
            $whitelist: []

    App\EventListener\LogSystem\EventLoggerListener:
        arguments:
            $save_changed_fields: '%env(bool:HISTORY_SAVE_CHANGED_FIELDS)%'
            $save_changed_data: '%env(bool:HISTORY_SAVE_CHANGED_DATA)%'
            $save_removed_data: '%env(bool:HISTORY_SAVE_REMOVED_DATA)%'
            $save_new_data: '%env(bool:HISTORY_SAVE_NEW_DATA)%'

    App\Form\AttachmentFormType:
        arguments:
            $allow_attachments_download: '%partdb.attachments.allow_downloads%'
            $max_file_size: '%partdb.attachments.max_file_size%'
            $download_by_default: '%partdb.attachments.download_by_default%'

    App\Services\Attachments\AttachmentSubmitHandler:
        arguments:
            $allow_attachments_downloads: '%partdb.attachments.allow_downloads%'
            $mimeTypes: '@mime_types'
            $max_upload_size: '%partdb.attachments.max_file_size%'

    App\Services\LogSystem\EventCommentNeededHelper:
        arguments:
            $enforce_change_comments_for: '%partdb.enforce_change_comments_for%'

    ####################################################################################################################
    # Attachment system
    ####################################################################################################################

    Liip\ImagineBundle\Service\FilterService:
        alias: 'liip_imagine.service.filter'

    App\EntityListeners\AttachmentDeleteListener:
        tags:
            - name: doctrine.orm.entity_listener

    App\Services\Attachments\AttachmentPathResolver:
        arguments:
            $project_dir: '%kernel.project_dir%'
            $media_path: '%partdb.attachments.dir.media%'
            $secure_path: '%partdb.attachments.dir.secure%'
            $footprints_path: 'public/img/footprints'
            $models_path: null

    App\Services\Attachments\FileTypeFilterTools:
        arguments:
            $mimeTypes: '@mime_types'

    ####################################################################################################################
    # Security
    ####################################################################################################################

    saml_user_factory:
        alias: App\Security\SamlUserFactory
        public: true

    App\Security\SamlUserFactory:
        arguments:
            $saml_role_mapping: '%env(json:SAML_ROLE_MAPPING)%'
            $update_group_on_login: '%env(bool:SAML_UPDATE_GROUP_ON_LOGIN)%'


    security.access_token_extractor.header.token:
        class: Symfony\Component\Security\Http\AccessToken\HeaderAccessTokenExtractor
        arguments:
            $tokenType: 'Token'

    security.access_token_extractor.main:
        class: Symfony\Component\Security\Http\AccessToken\ChainAccessTokenExtractor
        arguments:
            $accessTokenExtractors:
                - '@security.access_token_extractor.header'
                - '@security.access_token_extractor.header.token'

    ####################################################################################################################
    # Cache
    ####################################################################################################################

    App\EntityListeners\TreeCacheInvalidationListener:
        tags:
            - { name: doctrine.orm.entity_listener }

    ####################################################################################################################
    # Price system
    ####################################################################################################################
    App\Command\Currencies\UpdateExchangeRatesCommand:
        arguments:
            $base_current: '%partdb.default_currency%'

    App\Form\Type\CurrencyEntityType:
        arguments:
            $base_currency: '%partdb.default_currency%'

    App\Services\Parts\PricedetailHelper:
        arguments:
            $base_currency: '%partdb.default_currency%'

    App\Services\Formatters\MoneyFormatter:
        arguments:
            $base_currency: '%partdb.default_currency%'

    App\Services\Tools\ExchangeRateUpdater:
        arguments:
            $base_currency: '%partdb.default_currency%'

    ###################################################################################################################
    # User system
    ####################################################################################################################
    App\Form\UserSettingsType:
        arguments:
            $demo_mode: '%partdb.demo_mode%'

    App\EventSubscriber\UserSystem\SetUserTimezoneSubscriber:
        arguments:
            $default_timezone: '%partdb.timezone%'

    App\Controller\SecurityController:
        arguments:
            $allow_email_pw_reset: '%partdb.users.email_pw_reset%'

    App\Services\UserSystem\TFA\BackupCodeGenerator:
        arguments:
            $code_length: 8
            $code_count: 15

    App\Services\TranslationExtractor\PermissionExtractor:
        tags:
            - { name: 'translation.extractor', alias: 'permissionExtractor'}

    App\Services\UserSystem\UserAvatarHelper:
        arguments:
            $use_gravatar: '%partdb.users.use_gravatar%'

    App\Form\Type\ThemeChoiceType:
        arguments:
            $available_themes: '%partdb.available_themes%'

    App\Validator\Constraints\ValidThemeValidator:
        arguments:
            $available_themes: '%partdb.available_themes%'

    App\Command\User\ConvertToSAMLUserCommand:
        arguments:
            $saml_enabled: '%partdb.saml.enabled%'

    ####################################################################################################################
    # Table settings
    ####################################################################################################################
    App\DataTables\PartsDataTable:
        arguments:
            $visible_columns: '%partdb.table.parts.default_columns%'

    App\DataTables\Helpers\ColumnSortHelper:
        shared: false   # Service has a state so not share it between different tables

    ####################################################################################################################
    # Label system
    ####################################################################################################################
    App\Services\LabelSystem\LabelTextReplacer:
        arguments:
            $providers: !tagged_iterator 'app.label_placeholder_provider'

    # PartLotProvider must be invoked before all other providers, so it can override %%NAME%% placeholder
    App\Services\LabelSystem\PlaceholderProviders\PartLotProvider:
        tags:
            - { name: 'app.label_placeholder_provider', priority: 10}

    App\Services\LabelSystem\DompdfFactory:
        arguments:
            $fontDirectory: '%kernel.project_dir%/var/dompdf/fonts/'
            $tmpDirectory: '%kernel.project_dir%/var/dompdf/tmp/'

    ####################################################################################################################
    # Trees
    ####################################################################################################################
    App\Services\Trees\TreeViewGenerator:
        arguments:
            $rootNodeExpandedByDefault: '%partdb.sidebar.root_expanded%'
            $rootNodeEnabled: '%partdb.sidebar.root_node_enable%'

    ####################################################################################################################
    # Part info provider system
    ####################################################################################################################
    App\Services\InfoProviderSystem\ProviderRegistry:
        arguments:
            $providers: !tagged_iterator 'app.info_provider'

    App\Services\InfoProviderSystem\Providers\Element14Provider:
        arguments:
            $api_key: '%env(string:PROVIDER_ELEMENT14_KEY)%'
            $store_id: '%env(string:PROVIDER_ELEMENT14_STORE_ID)%'

    App\Services\InfoProviderSystem\Providers\DigikeyProvider:
        arguments:
            $clientId: '%env(string:PROVIDER_DIGIKEY_CLIENT_ID)%'
            $currency: '%env(string:PROVIDER_DIGIKEY_CURRENCY)%'
            $language: '%env(string:PROVIDER_DIGIKEY_LANGUAGE)%'
            $country: '%env(string:PROVIDER_DIGIKEY_COUNTRY)%'

    App\Services\InfoProviderSystem\Providers\TMEClient:
        arguments:
            $secret: '%env(string:PROVIDER_TME_SECRET)%'
            $token: '%env(string:PROVIDER_TME_KEY)%'

    App\Services\InfoProviderSystem\Providers\TMEProvider:
        arguments:
            $currency: '%env(string:PROVIDER_TME_CURRENCY)%'
            $country: '%env(string:PROVIDER_TME_COUNTRY)%'
            $language: '%env(string:PROVIDER_TME_LANGUAGE)%'
            $get_gross_prices: '%env(bool:PROVIDER_TME_GET_GROSS_PRICES)%'

    App\Services\InfoProviderSystem\Providers\OctopartProvider:
        arguments:
            $clientId: '&env(string:PROVIDER_OCTOPART_CLIENT_ID)%'
            $secret: '%env(string:PROVIDER_OCTOPART_SECRET)%'
            $country: '%env(string:PROVIDER_OCTOPART_COUNTRY)%'
            $currency: '%env(string:PROVIDER_OCTOPART_CURRENCY)%'
            $search_limit: '%env(int:PROVIDER_OCTOPART_SEARCH_LIMIT)%'
            $onlyAuthorizedSellers: '%env(bool:PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS)%'

    App\Services\InfoProviderSystem\Providers\MouserProvider:
        arguments:
            $api_key: '%env(string:PROVIDER_MOUSER_KEY)%'
            $language: '%env(string:PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE)%'
            $options: '%env(string:PROVIDER_MOUSER_SEARCH_OPTION)%'
            $search_limit: '%env(int:PROVIDER_MOUSER_SEARCH_LIMIT)%'

    App\Services\InfoProviderSystem\Providers\LCSCProvider:
        arguments:
            $enabled: '%env(bool:PROVIDER_LCSC_ENABLED)%'
            $currency: '%env(string:PROVIDER_LCSC_CURRENCY)%'

    App\Services\InfoProviderSystem\Providers\OEMSecretsProvider:
        arguments:
            $api_key: '%env(string:PROVIDER_OEMSECRETS_KEY)%'
            $country_code: '%env(string:PROVIDER_OEMSECRETS_COUNTRY_CODE)%'
            $currency: '%env(PROVIDER_OEMSECRETS_CURRENCY)%'
            $zero_price: '%env(PROVIDER_OEMSECRETS_ZERO_PRICE)%'
            $set_param: '%env(PROVIDER_OEMSECRETS_SET_PARAM)%'
            $sort_criteria: '%env(PROVIDER_OEMSECRETS_SORT_CRITERIA)%'


    ####################################################################################################################
    # API system
    ####################################################################################################################
    App\State\PartDBInfoProvider:
        arguments:
            $default_uri: '%partdb.default_uri%'
            $global_locale: '%partdb.locale%'
            $global_timezone: '%partdb.timezone%'

    ####################################################################################################################
    # EDA system
    ####################################################################################################################
    App\Services\EDA\KiCadHelper:
        arguments:
            $category_depth: '%env(int:EDA_KICAD_CATEGORY_DEPTH)%'

    ####################################################################################################################
    # Symfony overrides
    ####################################################################################################################

    # Dont use JSONSerializable Interface,
    serializer.normalizer.json_serializable:
        class: Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer
        tags:
          - {name: serializer.normalizer, priority: -9000}

    # Disable igbinary serialization for cache even when igbinary is available, as it causes issues with the doctrine
    # proxy objects (see https://github.com/igbinary/igbinary/issues/377 and https://github.com/igbinary/igbinary/issues/273)
    cache.default_marshaller:
        class: Symfony\Component\Cache\Marshaller\DefaultMarshaller
        arguments:
            $useIgbinarySerialize: false


    ####################################################################################################################
    # Miscellaneous
    ####################################################################################################################
    App\Controller\RedirectController:
        arguments:
            $default_locale: '%partdb.locale%'
            $enforce_index_php: '%env(bool:NO_URL_REWRITE_AVAILABLE)%'

    App\Doctrine\Purger\ResetAutoIncrementPurgerFactory:
        tags:
            - { name: 'doctrine.fixtures.purger_factory', alias: 'reset_autoincrement_purger' }

    # We are needing this service inside a migration, where only the container is injected. So we need to define it as public, to access it from the container.
    App\Services\UserSystem\PermissionPresetsHelper:
        public: true

    App\Command\BackupCommand:
        arguments:
            $project_dir: '%kernel.project_dir%'

    App\Services\System\UpdateAvailableManager:
        arguments:
            $check_for_updates: '%partdb.check_for_updates%'

    App\Services\System\BannerHelper:
        arguments:
            $partdb_banner: '%partdb.banner%'
            $project_dir: '%kernel.project_dir%'

    App\Doctrine\Middleware\MySQLSSLConnectionMiddlewareWrapper:
        arguments:
            $enabled: '%env(bool:DATABASE_MYSQL_USE_SSL_CA)%'
            $verify: '%env(bool:DATABASE_MYSQL_SSL_VERIFY_CERT)%'

    ####################################################################################################################
    # Monolog
    ####################################################################################################################
    # Add various monolog processors to log more information
    Symfony\Bridge\Monolog\Processor\WebProcessor:
        tags:
            - { name: monolog.processor }

    Symfony\Bridge\Monolog\Processor\ConsoleCommandProcessor:
        tags:
            - { name: monolog.processor }

    Symfony\Bridge\Monolog\Processor\TokenProcessor:
        autowire: true
        tags:
            - { name: monolog.processor }

when@test:
    services:
        # Decorate the doctrine fixtures load command to use our custom purger by default
        doctrine.fixtures_load_command.custom:
            decorates: doctrine.fixtures_load_command
            class: Doctrine\Bundle\FixturesBundle\Command\LoadDataFixturesDoctrineCommand
            arguments:
                - '@doctrine.fixtures.loader'
                - '@doctrine'
                - { default: '@App\Doctrine\Purger\DoNotUsePurgerFactory' }
