<?php

namespace Velis\VersionControl\Svn;

/**
 * Svn shell adapter
 * @author Bartosz Izdebski <bartosz.izdebski@velis.pl>
 */
class Shell implements Adapter
{

    /**
     * Repository URL
     * @var string
     */
    protected $_repositoryUrl;



    /**
     * Constructor
     * @param string $repositoryName
     */
    public function __construct($repositoryUrl)
    {
        $this->_repositoryUrl = $repositoryUrl;
    }


    /**
     * Return latest rev number
     * @return integer
     */
    public function getHeadRevision()
    {
        $command = 'svn info ' . $this->_repositoryUrl;
        exec($command, $output);

        $lineArray = explode(':', $output[4]);
        $rev = trim($lineArray[1]);

        return intval($rev);
    }


    /**
     * Info about revisions
     * @param int $revision
     * @param int limit (if null - all to head rev)
     * @return array
     */
    public function getInfo($revision, $limit = null)
    {
        $headRevision = $this->getHeadRevision();

        if ($revison > $headRevision) {
            $revision = $headRevision;
        }

        if (!$limit) {
            $limit = $headRevision - $revision;
        }

        $maxLimit = $headRevision - $revision;

        if ($limit <= $maxLimit) {
            $command = 'svn log -r ' . $revision . ':' . ($revision + $limit) . ' ' . $this->_repositoryUrl;
            exec($command, $output);

            $info = array();
            $infoRev = array();

            foreach ($output as $line) {
                if (strrpos($line, '-------------------------')) {
                    if (count($infoRev)) {
                        $infoRev['message'] = trim($infoRev['message']);
                        $info[$infoRev['rev']] = $infoRev;
                    }
                    $infoRev = array();
                } else {
                    if (count($infoRev) == 0) {
                        $infoLineArray = explode('|', $line);
                        $infoRev['rev'] = substr(trim($infoLineArray[0]), 1);
                        $infoRev['user'] = trim($infoLineArray[1]);
                        $infoRev['date'] = substr(trim($infoLineArray[2]), 0, 19);
                        $infoRev['message'] = '';
                    } else {
                        if ($line) {
                            $infoRev['message'] .= $line . PHP_EOL;
                        }
                    }
                }
            }

            return $info;
        } else {
            return array();
        }
    }


    /**
     * Info about changed files in revision
     * @param int $revision
     * @return array
     */
    public function getFiles($revision)
    {
        $command = 'svn diff -c ' . $revision . ' --summarize ' . $this->_repositoryUrl;
        exec($command, $output);

        $changelog = array();

        foreach ($output as $change) {
            $change = preg_replace('/[ ]+/', ';', trim($change));
            $changeArray = explode(";", $change);
            $changelog[] = array(
                'operation' => $changeArray[0],
                'file' => str_replace($this->_repositoryUrl, '', $changeArray[1])
            );
        }

        return $changelog;
    }
}
