<?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\ViisonCommon\Classes\Installation\Document;

use Shopware\Plugins\ViisonCommon\Classes\Installation\SQLHelper;
use Zend_Db_Adapter_Abstract;

/**
 * @deprecated Use DocumentInstallationHelper instead.
 */
class InstallationHelper
{
    /**
     * @var SQLHelper $sqlHelper
     */
    private $sqlHelper;

    /**
     * @var Zend_Db_Adapter_Abstract $db
     */
    private $db;

    /**
     * @param Zend_Db_Adapter_Abstract $db
     */
    public function __construct(Zend_Db_Adapter_Abstract $db)
    {
        $this->db = $db;
        $this->sqlHelper = new SQLHelper($db);
    }

    /**
     * Create or update a document type identified by name.
     *
     * @deprecated Use self::ensureDocumentType() instead.
     *
     * @param string $documentTypeName name of the document type to create or update. This is a unique identifier.
     * @param string $template the template to use
     * @param string $numbersGeneratorName the name of the numbers generator to use
     * @param int $left left margin to set
     * @param int $right right margin to set
     * @param int $top top margin to set
     * @param int $bottom bottom margin to set
     * @param int $pagebreak the number of items after which to force a page break
     * @return int the number of affected rows
     */
    public function ensureDocumentType(
        $documentTypeName,
        $template,
        $numbersGeneratorName,
        $left = 0,
        $right = 0,
        $top = 0,
        $bottom = 0,
        $pagebreak = 0
    ) {
        if (!$this->sqlHelper->doesRowExist('s_core_documents', ['name'], [$documentTypeName])) {
            return $this->sqlHelper->insertIfNotExists(
                's_core_documents',
                [
                    'name',
                    'template',
                    'numbers',
                    'left',
                    'right',
                    'top',
                    'bottom',
                    'pagebreak',
                ],
                [
                    $documentTypeName,
                    $template,
                    $numbersGeneratorName,
                    $left,
                    $right,
                    $top,
                    $bottom,
                    $pagebreak,
                ]
            );
        }

        return 0;
    }

    /**
     * @deprecated Use DocumentInstallationHelper::ensureDocumentType() instead.
     *
     * Create or update a document type identified by key.
     *
     * If SW version older than 5.5 is used, the name is used for identification.
     *
     * @param string $key the key (unique technical name for identification)
     * @param string $name name of the document type
     * @param string $template the template to use
     * @param string $numberRangeName the name of the numbers generator to use
     * @param int $left left margin to set
     * @param int $right right margin to set
     * @param int $top top margin to set
     * @param int $bottom bottom margin to set
     * @param int $pagebreak the number of items after which to force a page break
     * @return bool true if a DocumentType has been created.
     */
    public function ensureDocumentTypeWithKey(
        $key,
        $name,
        $template,
        $numberRangeName,
        $left = 0,
        $right = 0,
        $top = 0,
        $bottom = 0,
        $pagebreak = 0
    ) {
        // Use the key of the document type if possible, otherwise use the name
        $useKey = method_exists('Shopware\\Models\\Document\\Document', 'setKey');

        if ($useKey) {
            $documentTypeExists = $this->sqlHelper->doesRowExist('s_core_documents', ['key'], [$key]);
        } else {
            $documentTypeExists = $this->sqlHelper->doesRowExist('s_core_documents', ['name'], [$name]);
        }

        if ($documentTypeExists) {
            return 0;
        }

        $valueColumns = [
            'template' => $template,
            'numbers' => $numberRangeName,
            'left' => $left,
            'right' => $right,
            'top' => $top,
            'bottom' => $bottom,
            'pagebreak' => $pagebreak,
            'name' => $name,
        ];

        if ($useKey) {
            $valueColumns['key'] = $key;
        }

        return $this->db->insert('s_core_documents', $valueColumns);
    }

    /**
     * Creates a new document box, if no box with the given $boxName already exists for the document
     * having the given $documentTypeName.
     *
     * @deprecated Use DocumentInstallationHelper::ensureDocumentElement() instead.
     *
     * @param string $documentTypeName name of the document type to add the box for
     * @param string $boxName name of the box to add or update
     * @param string $style the style to set for the box
     * @param string $value the default value to set for the box
     * @return int the number of affected rows
     * @throws \InvalidArgumentException if the document was not found
     */
    public function ensureDocumentBox($documentTypeName, $boxName, $style = '', $value = '')
    {
        // Try to find the document by name
        $documentId = $this->getDocumentId($documentTypeName);
        if ($documentId === false) {
            throw new \InvalidArgumentException(
                sprintf('Cannot add document box "%s" because document type "%s" was not found', $boxName, $documentTypeName)
            );
        }

        // Try to find the box by name
        $boxExists = $this->sqlHelper->doesRowExist('s_core_documents_box', ['documentID', 'name'], [$documentId, $boxName]);
        if ($boxExists) {
            return 0;
        }

        // Write the box to the database
        $this->db->query(
            'INSERT INTO s_core_documents_box (documentID, name, style, value)
            VALUES (:documentId, :name, :style, :value)',
            [
                'documentId' => $documentId,
                'name' => $boxName,
                'style' => $style,
                'value' => $value,
            ]
        );

        return 1;
    }

    /**
     * Rename an entry in s_core_documents_box safely (i.e. in an idempotent manner).
     *
     * @deprecated Use DocumentInstallationHelper::renameDocumentBox() instead.
     *
     * @param string $documentType the name of the document type to update a box for
     * @param string $oldName the current name of the document box to rename
     * @param string $newName the desired new name of the document box
     */
    public function renameDocumentBox($documentType, $oldName, $newName)
    {
        $documentTypeId = $this->getDocumentId($documentType);
        if (!$documentTypeId) {
            throw new \InvalidArgumentException(sprintf('Document type "%s% not found.', $documentType));
        }

        if (!$this->sqlHelper->doesRowExist('s_core_documents_box', ['documentID', 'name'], [$documentTypeId, $newName])) {
            $this->db->query(
                'UPDATE s_core_documents_box
                SET name = :newName
                WHERE name = :oldName
                AND documentID = :documentTypeId',
                [
                    ':oldName' => $oldName,
                    ':newName' => $newName,
                    ':documentTypeId' => $documentTypeId,
                ]
            );
        } elseif ($this->sqlHelper->doesRowExist('s_core_documents_box', ['documentID', 'name'], [$documentTypeId, $oldName])) {
            // If versions that are installed / updated include both the creation of the $oldName box and its rename to
            // $newName, and the install crashes after this point, the original box will be re-created.
            // To handle this case cleanly, delete the re-created sequence here.
            $this->db->query(
                'DELETE FROM s_core_documents_box
                WHERE name = :oldName
                AND documentID = :documentTypeId',
                [
                    ':oldName' => $oldName,
                    ':documentTypeId' => $documentTypeId,
                ]
            );
        }
    }

    /**
     * @deprecated Use \Shopware\Plugins\ViisonCommon\Classes\Util\Document::getDocumentType(...)->getId() instead.
     *
     * @param $documentTypeName
     * @return string the document type id for the document with the given name
     */
    public function getDocumentTypeId($documentTypeName)
    {
        return $this->db->fetchOne(
            'SELECT id
            FROM s_core_documents
            WHERE `name` = :name',
            [
                'name' => $documentTypeName,
            ]
        );
    }

    /**
     * @deprecated Use \Shopware\Plugins\ViisonCommon\Classes\Util\Document::getDocumentType()->getId() instead.
     *
     * @param $documentTypeName
     * @return string the document type id for the document with the given name
     */
    public function getDocumentId($documentTypeName)
    {
        return $this->getDocumentTypeId($documentTypeName);
    }
}
