<?php

namespace Velis\VersionControl\Git\Repository;

use Velis\Model\DataObject;
use Velis\App;
use Velis\Arrays;
use Velis\Output;
use Velis\VersionControl\Git\Repository;

/**
 * Repository revision model
 *
 * @author Bartosz Izdebski <bartosz.izdebski@velis.pl>
 * @author Olek Procki <olo@velis.pl>
 */
class Revision extends DataObject
{

    const TESTS_STATUS_SUCCESS = 2;

    /**
     * Returns related sql table
     * @return string
     */
    protected function _getTableName()
    {
        return 'app.repository_revision_tab';
    }


    /**
     * Returns datasource for listing function
     * @return string
     */
    protected function _getListDatasource()
    {
        return 'app.repository_revision rr';
    }


    /**
     * Returns revisions list
     *
     * @param int $page
     * @param array|ArrayObject $params
     * @param string $order
     * @param int $limit
     * @param string|array $fields
     *
     * @return \Velis\Bpm\Ticket\Ticket[]
     */
    public static function getList($page = 1, $params = null, $order = null, $limit = self::ITEMS_PER_PAGE, $fields = null)
    {
        if ($params['branch']) {
            self::$_listConditions[] = "branch LIKE :branch";
            self::$_listParams['branch'] = '%' . $params['branch'] . '%';
            unset($params['branch']);
        }

        return parent::getList($page, $params, $order, $limit, $fields);
    }


    /**
     * Return the Repository object
     *
     * @return Repository
     */
    public function getRepository()
    {
        return Repository::get($this->repository_id);
    }


    /**
     * Get URL to phabricator page for comparing a revision to the previous one
     *
     * @return string
     */
    public function getCompareUrl()
    {
        $repository = $this->getRepository();
        if ($repository->url) {
            $repositoryUrl = 'https://' . preg_replace(['/(git@)|(\.git)/', '/org:/'], ['', 'org/'], $repository->url);
            return $repositoryUrl . '/commits/' . $this->revision_no;
        }
    }


    /**
     * Returns current PHPCI tests status
     * @return array
     */
    public static function getCurrentTestsStatus()
    {
        $rv = [];
        $query = "SELECT 
                    rb.repository_id,
                    rb.branch,
                    rb.repository_revision_id,
                    rr.revision_date,
                    rr.message,
                    CASE 
                        WHEN rb.branch = 'master' AND rb.failed_at_repository_revision_id IS NOT NULL THEN -1
                          WHEN 
                            rb.branch = 'master' 
                            AND (SELECT count(*) FROM app.repository_revision_tab rr3 
                                    WHERE rr3.repository_id = rb.repository_id 
                                    AND rr3.repository_revision_id > rr.repository_revision_id 
                                    AND rr3.branch = rr.branch
                                ) > 0 
                            THEN 0
                      ELSE rr.tests_status
                    END AS status,
                    COALESCE(rr2.status_change_date, rr2.revision_date) AS failed_revision_date,
                    rr2.revision_no AS failed_revision_no,
                    rr2.repository_login AS failed_user_login,
                    rr.e2e_tests_status,
                    rr.unit_tests_status,
                    rr.integration_tests_status,
                    rr.security_tests_status,
                    rr.puppeteer_tests_status
                FROM app.repository_branch_tab rb
                LEFT JOIN app.repository_revision_tab rr USING(repository_revision_id)
                LEFT JOIN app.repository_revision_tab rr2 ON rr2.repository_revision_id = rb.failed_at_repository_revision_id";


        foreach (self::$_db->getAll($query, null) as $revision) {
            $revision['failed_since'] = Output::getTimeAgo($revision['failed_revision_date']);
            $revision['failed_user_full_name'] = trim(Arrays::getFirst(explode(' (', $revision['failed_user_login'])));
            $rv[$revision['repository_id']][$revision['branch']] = $revision;
        }

        return $rv;
    }
}
