#!/usr/bin/env php
<?php

/** Options */
$releases = array('fix', 'patch', 'minor', 'major');

$type = current(array_intersect($argv, $releases));

if(!$type) {
    die(usage());
}

if(`git status --porcelain`) {
    die("Working directory must be clean. Run 'git status'\n\n");
}

$force = in_array('--force', $argv);
$push = in_array('--push', $argv);
$rebase = in_array('--rebase', $argv);

/* Check current branch */
$branch = trim(`git rev-parse --abbrev-ref HEAD`);

if($branch !== 'master' && !$force) {
    die("Can't release non-master branch '$branch'. Use '--force'.\n\n");
}

// Make sure we are on head of origin
$output = null; $return = null;
if($rebase) {
    exec('git pull --rebase', $output, $return);
} else {
    exec('git pull --ff-only', $output, $return);
}
if($return !== 0) {
    die("Failed merging origin. Probably requires manual fix.");
}

$versionFile = 'VERSION';

if(!file_exists($versionFile)) {
    $version = '0.0.0';
    file_put_contents($versionFile, $version);
} else {
    $version = file_get_contents($versionFile);
}

/**
 * @return string
 */
function usage(){
    return "Usage: bin/tag-release [patch|minor|major] [--push] [--force]\n"
        . "  --push    Also pushes branch and tags to origin\n"
        . "  --force   Applies release to non-master branch\n";
}

$oldVersion = $version;
$version = incrementVersion($version, $type);

function run($cmd) {
    echo "$cmd\n";
    `$cmd`;
}

file_put_contents($versionFile, $version);
$message = escapeshellarg("$version: " . str_replace("$oldVersion: ", '', trim(`git log -1 --pretty=%B`)));

run("git commit VERSION -m $message");
run("git tag -a $version -m 'Release $version'");

echo "Version is $version\n";

if($push) {
    run('git push --follow-tags');
}

/* Run post-tag-cmd scripts if present */
exec('composer run-script -l 2>&1 | grep post-tag-cmd > /dev/null && composer post-tag-cmd');

function incrementVersion($version, $type) {
    $bits = explode('.', $version);
    if(empty($bits[0])) {
        $bits[0] = 1;
    }
    if(empty($bits[1])) {
        $bits[1] = 0;
    }
    if(empty($bits[2])) {
        $bits[2] = 0;
    }

    if($type == 'fix' || $type == 'patch') {
        $bits[2] += 1;
    }
    elseif($type == 'minor') {
        $bits[1] += 1;
        $bits[2] = 0;
    }
    elseif($type == 'major') {
        $bits[0] += 1;
        $bits[1] = 0;
        $bits[2] = 0;
    }

    return implode('.', $bits);
}
