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

class PluginCompatibilityConstraint extends Struct
{
    /**
     * The name of the module the plugin belongs to
     * (Frontend | Backend | Core). "null" indicates,
     * that the plugin uses the new plugin system
     * introduced with Shopware 5.2.
     *
     * @var string|null
     */
    protected $module;

    /**
     * The internal name of the plugin.
     *
     * @var string
     */
    protected $plugin;

    /**
     * The minimum required version of the plugin
     * in semver format (MAJOR.MINOR.PATCH).
     *
     * @link http://semver.org/
     *
     * @var string
     */
    protected $minimumVersion;

    /**
     * Cutom message, which will be shown to the
     * user if the compatibility constraint isn't
     * solved (if no custom message is set (value
     * "null") a default message will be shown).
     *
     * @var string|null
     */
    protected $customMessage;

    /**
     * A flag to contol, whether to fail the constraint, if the respective plugin is not installed.
     * This option can be set to 'true' to test configure this constraints, to check for the plugin
     * and its minimum version. That is, to meet the constraint, the plugin must be installed in a
     * sufficient version.
     *
     * @var boolean
     */
    protected $pluginRequired;

    /**
     * For some compatibility checks we do not simply want to compare plugin names and versions.
     * A custom check can be stored as an anonymous function here. If this customCheck is set, it will be
     * executed without further checks.
     *
     * @var callable
     */
    protected $customCheck;

    /**
     * This is the caption of the button that leads to additional information.
     * It is optional: if it is not set a default title will be used.
     *
     * @var string|null
     */
    protected $linkTitle;

    /**
     * For some compatibility checks we want additional information linked in the growl message.
     * A new button is added to the growl message with a link to more information. This is this link.
     * Leave empty if no additional button should be created.
     *
     * @var string|null
     */
    protected $link;

    public function __construct(
        $module = null,
        $plugin = null,
        $minimumVersion = null,
        $customMessage = null,
        $pluginRequired = false,
        $customCheck = null,
        $link = null,
        $linkTitle = null
    ) {
        $this->module = $module;
        $this->plugin = $plugin;
        $this->minimumVersion = $minimumVersion;
        $this->customMessage = $customMessage;
        $this->pluginRequired = $pluginRequired;
        $this->customCheck = $customCheck;
        $this->link = $link;
        $this->linkTitle = $linkTitle;
    }

    /**
     * Set the value of Module
     *
     * @param mixed module
     *
     * @return self
     */
    public function setModule($module)
    {
        $this->module = $module;

        return $this;
    }

    /**
     * Set the value of Plugin
     *
     * @param mixed plugin
     *
     * @return self
     */
    public function setPlugin($plugin)
    {
        $this->plugin = $plugin;

        return $this;
    }

    /**
     * Set the value of Minimum Version
     *
     * @param mixed minimumVersion
     *
     * @return self
     */
    public function setMinimumVersion($minimumVersion)
    {
        $this->minimumVersion = $minimumVersion;

        return $this;
    }

    /**
     * Sets a custom message, which will be show to
     * the user, in case that the constraint isn't
     * solved.
     *
     * @param string|null  $customMessage  (null = use default message)
     */
    public function setCustomMessage($customMessage)
    {
        $this->customMessage = $customMessage;

        return $this;
    }

    /**
     * Get the value of Module
     *
     * @return mixed
     */
    public function getModule()
    {
        return $this->module;
    }

    /**
     * Get the value of Plugin
     *
     * @return mixed
     */
    public function getPlugin()
    {
        return $this->plugin;
    }

    /**
     * Get the value of Minimum Version
     *
     * @return mixed
     */
    public function getMinimumVersion()
    {
        return $this->minimumVersion;
    }

    /**
     * Return the value of Custom Message.
     *
     * @return string|null
     */
    public function getCustomMessage()
    {
        return $this->customMessage;
    }

    /**
     * @return boolean
     */
    public function isPluginRequired()
    {
        return $this->pluginRequired;
    }

    /**
     * @param boolean $pluginRequired
     */
    public function setPluginRequired($pluginRequired)
    {
        $this->pluginRequired = $pluginRequired;
    }

    /**
     * Checks whether a custom message is
     * set for this constraint or not.
     *
     * @return boolean
     */
    public function hasCustomMessage()
    {
        return $this->customMessage !== null;
    }

    /**
     * Checks whether the plugin uses the new plugin system
     * introduced with Shopware 5.2 or not.
     *
     * In order to be downward compatible, this property is
     * derived by convention from the plugins module name. If
     * not set (module name is "null"), the plugin is treated
     * as using the new plugin system.
     *
     * @return boolean
     */
    public function usesNewPluginSystem()
    {
        return $this->module === null;
    }

    /**
     * Sets a custom compatibility check. This parameter must be given as anonymous function.
     *
     * The custom function should return FALSE if the growl message should be shown (there is an issue).
     * It should return TRUE if the compatibility is ensured and no growl message should be shown.
     *
     * @param callable $customCheck
     */
    public function setCustomCheck($customCheck)
    {
        $this->customCheck = $customCheck;
    }

    /**
     * Executes the custom compatibility check.
     * Remark: true equals a check "pass" and no growl message is displayed
     */
    public function passesCustomCheck()
    {
        return ($this->customCheck) ? $this->customCheck->__invoke() : true;
    }

    /**
     * Sets custom link to additional information for this constraint.
     *
     * @param $link
     */
    public function setLink($link)
    {
        $this->link = $link;
    }

    /**
     * @param $linkTitle
     */
    public function setLinkTitle($linkTitle)
    {
        $this->linkTitle = $linkTitle;
    }

    /**
     * @return string|null
     */
    public function getLink()
    {
        return $this->link;
    }

    /**
     * @return string|null
     */
    public function getLinkTitle()
    {
        return $this->linkTitle;
    }
}
