#!/usr/bin/env php
<?php
if (!ini_get('date.timezone')) {
    ini_set('date.timezone', 'Europe/Amsterdam');
}

foreach (array(__DIR__ . '/../../../autoload.php'
, __DIR__ . '/../vendor/autoload.php'
, __DIR__ . '/vendor/autoload.php'
, getcwd() . '/vendor/autoload.php') as $file) {
    if (file_exists($file)) {
        define('BLEND_COMPOSER_INSTALL', $file);
        break;
    }
}

unset($file);

if (!defined('BLEND_COMPOSER_INSTALL')) {
    fwrite(STDERR, 'You need to set up the project dependencies using the following commands:' . PHP_EOL .
            'wget http://getcomposer.org/composer.phar' . PHP_EOL .
            'php composer.phar install' . PHP_EOL
    );
    die(1);
}

require BLEND_COMPOSER_INSTALL;

use Blend\Component\Support\Version;
use Blend\Framework\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;

class BumpVersionCommand extends Command {

    /**
     * @var Blend\Component\Support\Version
     */
    private $version;
    private $branch;

    public function __construct(Version $version, $name = null) {
        $this->version = $version;
        parent::__construct($name);
    }

    protected function configure() {
        $this->setName('version')
                ->setDescription('Creates a new release version: default build ' . $this->version->getBuild())
                ->addOption('bump', 'b', InputOption::VALUE_REQUIRED, 'The version part', 'build');
    }

    protected function execute(InputInterface $input, OutputInterface $output) {
        $output->writeln("Current version: " . $this->version->getVersion());
        $this->branch = $this->getCurrentGitBranch();
        if ($this->branch === "master") {
            if ($this->isBranchClean()) {
                $versionPart = $this->getAssetVersionPart($input->getOption("bump", "build"));

                switch ($versionPart) {
                    case "marjor":
                        $this->version->bumpMajor();
                        break;
                    case "minor":
                        $this->version->bumpMinor();
                        break;
                    case "build":
                        $this->version->bumpBuild();
                        break;
                    case "release":
                        $this->version->serReleaseTag($versionPart);
                        break;
                    default:
                        $this->version->bumpBuild();
                }
                $output->writeln("Bumping to: " . $this->version->getVersion());

                $helper = $this->getHelper('question');
                $question = new ConfirmationQuestion('Continue with this action?', false);

                if ($helper->ask($input, $output, $question)) {
                    $this->createNewGitTag($output);
                    $this->pushToRepository($output);
                }
            } else {
                throw new Exception("$this->branch branch is not clean yet!");
            }
        } else {
            throw new Exception("Cannot relase from the $this->branch branch, only master is allowed!");
        }
    }

    private function pushToRepository(OutputInterface $output) {
        $output->writeln("Pushing to repository");
        return `git push origin master --follow-tags`;
    }

    private function createNewGitTag(OutputInterface $output) {
        $version = $this->version->getVersion();
        $output->writeln("Tagging to: " . $version);
        return `git tag -a $version -m"Release version $version"`;
    }

    private function getAssetVersionPart($value) {
        $value = strtolower($value);
        $allowed = array("major", "minior", "build", "release");
        if (!in_array($value, $allowed)) {
            throw new Exception("Invalid bump value $value. Only major, minor, build, or relase are allowed!");
        }
        return $value;
    }

    private function getCurrentGitBranch() {
        return trim(`git rev-parse --abbrev-ref HEAD`);
    }

    private function isBranchClean() {
        $result = trim(`git status --porcelain`);
        return empty($result);
    }

}

class ReleaseApplication extends Application {

    private function getLatestTagVersion() {
        $data = explode("\n", trim(`git tag`));
        if (!empty($data)) {
            return trim($data[count($data) - 1]);
        } else {
            return null;
        }
    }

    public function __construct($script_dir) {
        $this->version = new Version($this->getLatestTagVersion());
        parent::__construct($script_dir, 'BlendEngine Release Tool, Current Version: ' . $this->version->getVersion());
        $command = new BumpVersionCommand($this->version);
        $this->add($command);
        $this->setDefaultCommand($command->getName());
    }

}

$app = new ReleaseApplication(__DIR__);
$app->run();
