<?xml version="1.0"?>
<!--
  @copyright  Vertex. All rights reserved.  https://www.vertexinc.com/
  @author     Mediotype                     https://www.mediotype.com/
  -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!-- API Preferences -->
    <preference for="Vertex\Tax\Api\Data\LogEntryInterface" type="Vertex\Tax\Model\Data\LogEntry"/>
    <preference for="Vertex\Tax\Api\Data\LogEntrySearchResultsInterface"
                type="Magento\Framework\Api\SearchResultsInterface"/>
    <preference for="Vertex\Tax\Api\LogEntryRepositoryInterface" type="Vertex\Tax\Model\Repository\LogEntryRepository"/>
    <preference for="Vertex\Tax\Model\TaxRegistry\StorageInterface" type="Vertex\Tax\Model\TaxRegistry\CacheStorage" />
    <type name="Vertex\Tax\Model\TaxRegistry\CacheStorage">
        <arguments>
            <argument name="cache" xsi:type="object">Vertex\Tax\Model\Cache\Type</argument>
        </arguments>
    </type>

    <preference for="Vertex\Tax\Api\ClientInterface" type="Vertex\Tax\Model\ApiClient"/>
    <preference for="Vertex\Tax\Api\InvoiceInterface" type="Vertex\Tax\Service\InvoiceProxy"/>
    <preference for="Vertex\Tax\Api\QuoteInterface" type="Vertex\Tax\Service\QuoteProxy"/>
    <preference for="Vertex\Tax\Api\TaxAreaLookupInterface" type="Vertex\Tax\Service\TaxAreaLookupProxy"/>

    <!-- Service Builders -->
    <type name="Vertex\Tax\Model\Api\Service\InvoiceBuilder" shared="false" />
    <type name="Vertex\Tax\Model\Api\Service\QuoteBuilder" shared="false" />
    <type name="Vertex\Tax\Model\Api\Service\TaxAreaLookupBuilder" shared="false" />

    <!-- Builders for SDK Interfaces -->
    <type name="Vertex\Tax\Model\Api\Data\AddressBuilder" shared="false" />
    <type name="Vertex\Tax\Model\Api\Data\SellerBuilder" shared="false" />
    <type name="Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\InvoiceProcessor">
        <arguments>
            <argument name="processorPool" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\InvoiceProcessorPool</argument>
        </arguments>
    </type>
    <type name="Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\InvoiceProcessorPool">
        <arguments>
            <argument name="processors" xsi:type="array">
                <item name="invoice-item" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\InvoiceItemProcessor</item>
                <item name="shipping" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\InvoiceShippingProcessor</item>
                <item name="giftwrap" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\InvoiceGiftwrapProcessor</item>
            </argument>
        </arguments>
    </type>
    <type name="Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\OrderProcessor">
        <arguments>
            <argument name="processorPool" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\OrderProcessorPool</argument>
        </arguments>
    </type>
    <type name="Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\OrderProcessorPool">
        <arguments>
            <argument name="processors" xsi:type="array">
                <item name="order-item" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\OrderItemProcessor</item>
                <item name="shipping" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\OrderShippingProcessor</item>
                <item name="giftwrap" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\OrderGiftwrapProcessor</item>
            </argument>
        </arguments>
    </type>
    <type name="Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\CreditmemoProcessor">
        <arguments>
            <argument name="processorPool" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\CreditmemoProcessorPool</argument>
        </arguments>
    </type>
    <type name="Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\CreditmemoProcessorPool">
        <arguments>
            <argument name="processors" xsi:type="array">
                <item name="creditmemo-item" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\CreditmemoItemProcessor</item>
                <item name="shipping" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\CreditmemoShippingProcessor</item>
                <item name="giftwrap" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\CreditmemoGiftwrapProcessor</item>
                <item name="adjustments" xsi:type="object">Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder\CreditmemoAdjustmentProcessor</item>
            </argument>
        </arguments>
    </type>

    <!-- Workaround for issue discovered in Magento 2.1.8 where preference doesn't exist for CustomerExtensionInterface -->
    <preference for="Magento\Customer\Api\Data\CustomerExtensionInterface" type="Magento\Customer\Api\Data\CustomerExtension"/>

    <!-- Plugins -->
    <type name="Vertex\Utility\SoapClientFactory">
        <plugin name="registerLastCreatedClient" type="Vertex\Tax\Model\Plugin\SoapClientFactoryPlugin" />
    </type>
    <type name="Vertex\Utility\ServiceActionPerformerFactory">
        <plugin name="useObjectManager" type="Vertex\Tax\Model\Plugin\ServiceActionPerformerFactoryPlugin" />
    </type>
    <type name="Magento\Customer\Api\CustomerRepositoryInterface">
        <plugin name="extensionAttributeVertexCustomerCode" type="Vertex\Tax\Model\Plugin\CustomerRepositoryPlugin" />
    </type>

    <type name="Magento\Tax\Api\TaxCalculationInterface">
        <plugin name="vertexTaxCalculation" type="Vertex\Tax\Model\Plugin\TaxCalculationPlugin" sortOrder="1" />
    </type>
    <type name="Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector">
        <plugin name="vertexItemLevelMap" type="Vertex\Tax\Model\Plugin\CommonTaxCollectorPlugin" sortOrder="1" />
    </type>
    <type name="Magento\Tax\Model\Sales\Total\Quote\Subtotal">
        <plugin name="vertexDoesNotCalculateSubtotal" type="Vertex\Tax\Model\Plugin\SubtotalPlugin" sortOrder="10" />
    </type>
    <type name="Magento\Tax\Model\Sales\Total\Quote\Tax">
        <plugin name="vertexOrderLevelMap" type="Vertex\Tax\Model\Plugin\TaxPlugin" sortOrder="1" />
    </type>

    <type name="Magento\Sales\Block\Adminhtml\Order\Create\Form">
        <plugin name="PrepareVertexResponseMessages" type="Vertex\Tax\Block\Plugin\OrderCreateFormPlugin" sortOrder="1" />
    </type>
    <type name="Magento\Sales\Block\Adminhtml\Order\Create\Totals">
        <plugin name="PrepareVertexResponseMessages" type="Vertex\Tax\Block\Plugin\OrderCreateTotalsPlugin" sortOrder="1" />
    </type>

    <!-- Vertex SDK -->
    <preference for="Vertex\Data\AddressInterface" type="Vertex\Data\Address"/>
    <preference for="Vertex\Data\ConfigurationInterface" type="Vertex\Data\Configuration"/>
    <preference for="Vertex\Data\CustomerInterface" type="Vertex\Data\Customer"/>
    <preference for="Vertex\Data\JurisdictionInterface" type="Vertex\Data\Jurisdiction"/>
    <preference for="Vertex\Data\LineItemInterface" type="Vertex\Data\LineItem"/>
    <preference for="Vertex\Data\LoginInterface" type="Vertex\Data\Login"/>
    <preference for="Vertex\Data\SellerInterface" type="Vertex\Data\Seller"/>
    <preference for="Vertex\Data\TaxInterface" type="Vertex\Data\Tax"/>
    <preference for="Vertex\Data\TaxAreaLookupResultInterface" type="Vertex\Data\TaxAreaLookupResult"/>
    <preference for="Vertex\Services\Invoice\RequestInterface" type="Vertex\Services\Invoice\Request"/>
    <preference for="Vertex\Services\Invoice\ResponseInterface" type="Vertex\Services\Invoice\Response"/>
    <preference for="Vertex\Services\Quote\RequestInterface" type="Vertex\Services\Quote\Request"/>
    <preference for="Vertex\Services\Quote\ResponseInterface" type="Vertex\Services\Quote\Response"/>
    <preference for="Vertex\Services\TaxAreaLookup\RequestInterface" type="Vertex\Services\TaxAreaLookup\Request"/>
    <preference for="Vertex\Services\TaxAreaLookup\ResponseInterface" type="Vertex\Services\TaxAreaLookup\Response"/>

    <!-- This wiring exists so the ObjectManager is utilized instead of defaulting to "null" and letting the SDK constructors handle it -->
    <preference for="Vertex\Utility\SoapFaultConverterInterface"
                type="Vertex\Utility\FaultConverter\PooledSoapFaultConverter"/>
    <type name="Vertex\Utility\FaultConverter\PooledSoapFaultConverter">
        <arguments>
            <argument name="converters" xsi:type="array">
                <item name="authenticationFailure" xsi:type="object">Vertex\Utility\FaultConverter\AuthenticationFailureConverter</item>
                <item name="connectionFailure" xsi:type="object">Vertex\Utility\FaultConverter\ConnectionFailure</item>
            </argument>
        </arguments>
    </type>

    <!-- Wiring for Services -->
    <type name="Vertex\Services\TaxAreaLookup">
        <arguments>
            <argument name="mapperFactory" xsi:type="object">Vertex\Mapper\MapperFactory</argument>
            <argument name="versionDeterminer" xsi:type="object">Vertex\Utility\VersionDeterminer</argument>
            <argument name="actionPerformerFactory" xsi:type="object">Vertex\Utility\ServiceActionPerformerFactory</argument>
        </arguments>
    </type>
    <type name="Vertex\Services\Quote">
        <arguments>
            <argument name="mapperFactory" xsi:type="object">Vertex\Mapper\MapperFactory</argument>
            <argument name="versionDeterminer" xsi:type="object">Vertex\Utility\VersionDeterminer</argument>
            <argument name="actionPerformerFactory" xsi:type="object">Vertex\Utility\ServiceActionPerformerFactory</argument>
        </arguments>
    </type>
    <type name="Vertex\Services\Invoice">
        <arguments>
            <argument name="mapperFactory" xsi:type="object">Vertex\Mapper\MapperFactory</argument>
            <argument name="versionDeterminer" xsi:type="object">Vertex\Utility\VersionDeterminer</argument>
            <argument name="actionPerformerFactory" xsi:type="object">Vertex\Utility\ServiceActionPerformerFactory</argument>
        </arguments>
    </type>

    <!-- Wiring for Mappers -->
    <type name="Vertex\Mapper\Api60\AddressMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\Authenticator">
        <arguments>
            <argument name="loginMapper" xsi:type="object">Vertex\Mapper\Api60\LoginMapper</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\CustomerMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
            <argument name="addressMapper" xsi:type="object">Vertex\Mapper\Api60\AddressMapper</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\InvoiceRequestMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
            <argument name="customerMapper" xsi:type="object">Vertex\Mapper\Api60\CustomerMapper</argument>
            <argument name="lineItemMapper" xsi:type="object">Vertex\Mapper\Api60\LineItemMapper</argument>
            <argument name="sellerMapper" xsi:type="object">Vertex\Mapper\Api60\SellerMapper</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\InvoiceResponseMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
            <argument name="customerMapper" xsi:type="object">Vertex\Mapper\Api60\CustomerMapper</argument>
            <argument name="sellerMapper" xsi:type="object">Vertex\Mapper\Api60\SellerMapper</argument>
            <argument name="lineItemMapper" xsi:type="object">Vertex\Mapper\Api60\LineItemMapper</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\JurisdictionMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\LineItemMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
            <argument name="customerMapper" xsi:type="object">Vertex\Mapper\Api60\CustomerMapper</argument>
            <argument name="sellerMapper" xsi:type="object">Vertex\Mapper\Api60\SellerMapper</argument>
            <argument name="taxMapper" xsi:type="object">Vertex\Mapper\Api60\TaxMapper</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\LoginMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\QuoteRequestMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
            <argument name="customerMapper" xsi:type="object">Vertex\Mapper\Api60\CustomerMapper</argument>
            <argument name="lineItemMapper" xsi:type="object">Vertex\Mapper\Api60\LineItemMapper</argument>
            <argument name="sellerMapper" xsi:type="object">Vertex\Mapper\Api60\SellerMapper</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\QuoteResponseMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
            <argument name="customerMapper" xsi:type="object">Vertex\Mapper\Api60\CustomerMapper</argument>
            <argument name="lineItemMapper" xsi:type="object">Vertex\Mapper\Api60\LineItemMapper</argument>
            <argument name="sellerMapper" xsi:type="object">Vertex\Mapper\Api60\SellerMapper</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\SellerMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
            <argument name="addressMapper" xsi:type="object">Vertex\Mapper\Api60\AddressMapper</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\TaxAreaLookupRequestMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
            <argument name="addressMapper" xsi:type="object">Vertex\Mapper\Api60\AddressMapper</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\TaxAreaLookupResponseMapper">
        <arguments>
            <argument name="resultMapper" xsi:type="object">Vertex\Mapper\Api60\TaxAreaLookupResultMapper</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\TaxAreaLookupResultMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
            <argument name="addressMapper" xsi:type="object">Vertex\Mapper\Api60\AddressMapper</argument>
            <argument name="jurisdictionMapper" xsi:type="object">Vertex\Mapper\Api60\JurisdictionMapper</argument>
        </arguments>
    </type>
    <type name="Vertex\Mapper\Api60\TaxMapper">
        <arguments>
            <argument name="utilities" xsi:type="object">Vertex\Mapper\MapperUtilities</argument>
            <argument name="jurisdictionMapper" xsi:type="object">Vertex\Mapper\Api60\JurisdictionMapper</argument>
        </arguments>
    </type>
</config>
