<?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;

use Zend_Db_Adapter_Abstract;

if (!class_exists('ViisonCommon_Plugin_BootstrapV8')) {
    require_once(__DIR__ . '/../../PluginBootstrapV8.php');
}

/**
 * A migration helper class to "checkpoint" migration steps during updates which span multiple versions. This is
 * sometimes required to prevent idempotency breaks, in particular when renaming tables or columns.
 */
class InstallationCheckpointWriter
{
    /**
     * @var string
     */
    private $pluginName;

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

    /**
     * @var boolean
     */
    private $isPluginInstallation;

    /**
     * @param \ViisonCommon_Plugin_BootstrapV8 $pluginBootstrap
     */
    public function __construct(\ViisonCommon_Plugin_BootstrapV8 $pluginBootstrap)
    {
        $this->pluginName = $pluginBootstrap->getName();
        $this->database = $pluginBootstrap->get('db');
        $this->isPluginInstallation = $pluginBootstrap->getPlugin()->getInstalled() === null;
    }

    /**
     * Checkpoints the given migration step by patching s_core_plugins.version. Use it like this:
     *
     * ```php
     * case '4.3.1':
     *   // Explain why you need to commit a checkpoint, and make sure this is the first thing in the migration step
     *   $installationCheckpointWriter->commitCheckpointAtVersion('4.3.1');
     *   // Add your migrations steps which break previous migrations (e.g. table or column renames) here
     * ```
     *
     * @param string $pluginVersion
     */
    public function commitCheckpointAtVersion($pluginVersion)
    {
        if ($this->isPluginInstallation) {
            // In case of an installation, we must not overwrite the plugin version in the database, because that would
            // prevent the actual plugin version from being written. That said, if an installation attempt fails after
            // committing a checkpoint, the next installation will start from the beginning anyway, so writing a
            // checkpoint is not necessary.
            return;
        }

        $this->database->query(
            'UPDATE `s_core_plugins`
            SET `version` = :pluginVersion
            WHERE `name` = :pluginName',
            [
                ':pluginVersion' => $pluginVersion,
                ':pluginName' => $this->pluginName,
            ]
        );
    }
}
