<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

namespace Shopware\Plugins\ViisonDHL\Classes;

use Shopware\Plugins\ViisonCommon\Components\FileStorage\FileStorage;
use Shopware\Plugins\ViisonDHL\Classes\DHLCommunication;
use Shopware\Plugins\ViisonDHL\Classes\DHLException;
use Shopware\Plugins\ViisonDHL\Util;
use Shopware\Plugins\ViisonShippingCommon\Classes\ShippingUtil as ShippingCommonUtil;
use Symfony\Component\Config\Definition\Exception\Exception;

/**
 * Class ShippingUtil
 *
 * Provides shipping specific utility functions. Implements the ShippingUtil interface from the
 * ShippingCommon module.
 *
 * @package Shopware\Plugins\ViisonDHL\Classes
 */
class ShippingUtil extends ShippingCommonUtil
{

    /**
     * @Override from ShippingCommon
     *
     * ShippingUtil constructor.
     */
    public function __construct()
    {
        parent::__construct(Util::instance());
    }

    /**
    * @Override from ShippingCommon
    *
    * Sends a request to the dispatch service provider to download the document of the given type
    * with the given tracking code and save it to the given file path.
    *
    * @param string $docType
    * @param string $trackingCode
    * @param string $path The file path where the document should be saved.
    * @return string|null A file containing the document.
    * @throws \Exception if the operation was not successful or is generally not supported by the dispatch service provider.
    */
    protected function loadDocumentFromDispatchServiceProvider($docType, $trackingCode, $path)
    {
        throw new \Exception('Adapter does not support downloading of documents after they were created.');
    }

    /**
     * @Override from ShippingCommon
     */
    public function getProductOptions($productId)
    {
        // Get the respective product code for the product ID
        $util = Util::instance();
        $exportDocumentCode = [
            'BPI',
            'ABI',
            'WPI',
        ];
        $productTable = new \Zend_Db_Table($util->getPluginInfo()->getProductTableName());
        $productCode = Shopware()->Db()->fetchOne(
            $productTable
            ->select()
            ->from($productTable, ['code'])
            ->where('id = ?', $productId)
        );

        // Determine the options based on the product code
        $options = [];
        if (in_array($productCode, $exportDocumentCode)) {
            $options[] = 'createExportDocument';
        }

        return $options;
    }

    /**
     * @Override from ShippingCommon
     *
     * First parses the given identifier to select the right document type and tracking code.
     * Then tries to find the requested document in the Shopware documents directory
     * and just return it. If it was not found, it uses the document type and tracking code
     * to request the document URL and finally load the file, which is then saved on disk and returned.
     *
     * @param string $identifier A string identifying the document, which shall be returned.
     * @return string A file containing the document.
     * @throws \Exception, if an unknown identifier was passed to this method or a request failed.
     */
    public function getDocument($identifier)
    {
        /** @var Util */
        $util = Util::instance();

        /**
         * Process the document identifier to determine the document type
         *
         * @var int $splitPos Get the position of ':'
         * @var string $docType Can be Label or Return Label
         * @var string $labelIdentifier The identifier used for Document Creation (Tracking Code, Vaoucher ID ...)
         */
        $splitPos = mb_strpos($identifier, ':');
        $docType = mb_substr($identifier, 0, $splitPos);
        $labelIdentifier = mb_substr($identifier, ($splitPos + 1));

        if (!in_array($docType, [self::DOCUMENT_TYPE_SHIPPING_LABEL, self::DOCUMENT_TYPE_EXPORT_DOCUMENT]) || mb_strlen($labelIdentifier) == 0) {
            // Unknown document type / invalid tracking code
            $util->log('Unknown identifier "' . $identifier . '".');
            throw new \Exception('Unknown identifier "' . $identifier . '".');
        }

        /** @var FileStorage $fileStorageService */
        $fileStorageService = Shopware()->Container()->get('viison_common.document_file_storage_service');
        $documentFileName = $util->getDocumentFileName($labelIdentifier, $docType);
        if ($fileStorageService->doesFileExist($documentFileName)) {
            // The document was already saved, so just retrieve and return it
            return $fileStorageService->readFileContents($documentFileName);
        }

        /** Fallback for OLD Intraship plugin, so we can open the old documents */
        $intrashipDocumentFileName = $util->getDocumentFileName($labelIdentifier, $docType, 'intraship');
        if ($fileStorageService->doesFileExist($intrashipDocumentFileName)) {
            // The old Intraship document was already saved, so just retrieve and return it
            return $fileStorageService->readFileContents($intrashipDocumentFileName);
        }

        // PDF not found, download it from the dispatch service provider if possible
        return $this->loadDocumentFromDispatchServiceProvider($docType, $labelIdentifier, $documentFileName);
    }

    /**
     * @Inheritdoc
     */
    protected function applyMinimumWeight($weight)
    {
        // DHL products need a lower minimum weight than the default 0.1kg
        return max($weight, 0.01);
    }
}
