<?php

/**
 * Matomo - free/libre analytics platform
 *
 * @link    https://matomo.org
 * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
 */
namespace Piwik\Plugins\CoreConsole\Commands;

use Piwik\Filesystem;
use Piwik\Plugins\ExamplePlugin\ExamplePlugin;
use Piwik\Plugin;
use Piwik\Version;
class GeneratePlugin extends \Piwik\Plugins\CoreConsole\Commands\GeneratePluginBase
{
    protected function configure()
    {
        $this->setName('generate:plugin')->setAliases(array('generate:theme'))->setDescription('Generates a new plugin/theme including all needed files')->addRequiredValueOption('name', null, 'Plugin name ([a-Z0-9_-])')->addRequiredValueOption('description', null, 'Plugin description, max 150 characters')->addOptionalValueOption('pluginversion', null, 'Plugin version')->addNoValueOption('overwrite', null, 'Generate even if plugin directory already exists.');
    }
    protected function doExecute() : int
    {
        $isTheme = $this->isTheme();
        $pluginName = $this->getPluginName();
        $description = $this->getPluginDescription();
        $version = $this->getPluginVersion();
        $this->generatePluginFolder($pluginName);
        $plugin = new ExamplePlugin();
        $info = $plugin->getInformation();
        $exampleDescription = $info['description'];
        if ($isTheme) {
            $exampleFolder = Plugin\Manager::getPluginDirectory('ExampleTheme');
            $replace = array('ExampleTheme' => $pluginName, $exampleDescription => $description, '0.1.0' => $version, '3.0.0-b1' => Version::VERSION);
            $whitelistFiles = array();
        } else {
            $exampleFolder = Plugin\Manager::getPluginDirectory('ExamplePlugin');
            $replace = array('ExamplePlugin' => $pluginName, $exampleDescription => $description, '0.1.0' => $version, '3.0.0-b1' => Version::VERSION);
            $whitelistFiles = array('/ExamplePlugin.php', '/plugin.json', '/README.md', '/CHANGELOG.md', '/screenshots', '/screenshots/.gitkeep', '/docs', '/docs/faq.md', '/docs/index.md', '/config', '/config/config.php', '/config/tracker.php');
        }
        $this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles);
        $this->checkAndUpdateRequiredPiwikVersion($pluginName);
        if ($isTheme) {
            $this->writeSuccessMessage(array(sprintf('Theme %s %s generated.', $pluginName, $version), 'If you have not done yet check out our Theming guide <comment>https://developer.matomo.org/guides/theming</comment>', 'Enjoy!'));
        } else {
            $this->writeSuccessMessage(array(sprintf('Plugin %s %s generated.', $pluginName, $version), 'Our developer guides will help you developing this plugin, check out <comment>https://developer.matomo.org/guides</comment>', 'To see a list of available generators execute <comment>./console list generate</comment>', 'Enjoy!'));
        }
        return self::SUCCESS;
    }
    /**
     * @return bool
     */
    private function isTheme()
    {
        $commandName = $this->getInput()->getFirstArgument();
        return \false !== strpos($commandName, 'theme');
    }
    protected function generatePluginFolder($pluginName)
    {
        $pluginPath = $this->getPluginPath($pluginName);
        Filesystem::mkdir($pluginPath);
    }
    /**
     * @return string
     * @throws \RuntimeException
     */
    protected function getPluginName()
    {
        $overwrite = $this->getInput()->getOption('overwrite');
        $self = $this;
        $validate = function ($pluginName) use($self, $overwrite) {
            if (empty($pluginName)) {
                throw new \RuntimeException('You have to enter a plugin name');
            }
            if (!Plugin\Manager::getInstance()->isValidPluginName($pluginName)) {
                throw new \RuntimeException(sprintf('The plugin name %s is not valid. The name must be no longer than 60 characters and start with a letter and is only allowed to contain numbers and letters.', $pluginName));
            }
            $pluginPath = $self->getPluginPath($pluginName);
            if (file_exists($pluginPath) && !$overwrite) {
                throw new \RuntimeException('A plugin with this name already exists');
            }
            return $pluginName;
        };
        $pluginName = $this->getInput()->getOption('name');
        if (empty($pluginName)) {
            $pluginName = $this->askAndValidate('Enter a plugin name: ', $validate);
        } else {
            $validate($pluginName);
        }
        $pluginName = ucfirst($pluginName);
        return $pluginName;
    }
    /**
     * @return mixed
     * @throws \RuntimeException
     */
    protected function getPluginDescription()
    {
        $validate = function ($description) {
            if (empty($description)) {
                throw new \RuntimeException('You have to enter a description');
            }
            if (150 < strlen($description)) {
                throw new \RuntimeException('Description is too long, max 150 characters allowed.');
            }
            return $description;
        };
        $description = $this->getInput()->getOption('description');
        if (empty($description)) {
            $description = $this->askAndValidate('Enter a plugin description: ', $validate);
        } else {
            $validate($description);
        }
        return $description;
    }
    /**
     * @return string
     */
    protected function getPluginVersion()
    {
        $version = $this->getInput()->getOption('pluginversion');
        if (is_null($version)) {
            $version = $this->ask('Enter a plugin version number (default to 0.1.0): ', '0.1.0');
        }
        return $version;
    }
}
