<?php
/**
 * SeekQuarry/Yioop --
 * Open Source Pure PHP Search Engine, Crawler, and Indexer
 *
 * Copyright (C) 2009 - 2026  Chris Pollett chris@pollett.org
 *
 * LICENSE:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * END LICENSE
 *
 * @author Chris Pollett chris@pollett.org
 * @license https://www.gnu.org/licenses/ GPL3
 * @link https://www.seekquarry.com/
 * @copyright 2009 - 2026
 * @filesource
 */
namespace seekquarry\yioop\views;

use seekquarry\yioop\configs as C;

/**
 *
 * Draws the view on which people can control
 * their search settings such as num links per screen
 * and the language settings
 *
 * @author Chris Pollett
 */
class TestsView extends View
{
    /**
     * This view is drawn on a web layout
     * @var string
     */
    public $layout = "web";
    /**
     * Draws the web page on which users can control their search settings.
     *
     * @param array $data passed from controller. It fields contain info
     *  about the possibble tests that can be run, which test activity to
     *  carry out, etc.
     */
    public function renderView($data)
    {
        $logged_in = !empty($data["ADMIN"]);
        $token_string = ($logged_in) ? "?" .C\p('CSRF_TOKEN')."=".
            $data[C\p('CSRF_TOKEN')] : "";
        $logo_field = "LOGO_LARGE";
        $logo = C\SHORT_BASE_URL . C\p('LOGO_LARGE');
        if ($_SERVER["MOBILE"]) {
            $logo_field = "LOGO_SMALL";
            $logo = C\SHORT_BASE_URL . C\p('LOGO_SMALL');
        }
        $logo = $this->helper("logo")->render($data,
            $logo_field, $logo);
        ?>
        <div class="group-heading logo"><div class="test">
        <h1 class="logo"><a href="<?=C\SHORT_BASE_URL .
            $token_string ?>"><img src="<?=$logo ?>"
            alt="<?=$this->logo_alt_text ?>" ></a><span> - <?=
            tl('tests_view_tests') ?></span>
        </h1>
        </div>
        </div>
        <div class="small-top" >
        <div class='current-activity'>
        <?php
            switch ($data['ACTIVITY']) {
                case "render_test":
                    $this->renderTest($data);
                break;
                case "render_selected_tests":
                    $this->renderSelectedTests($data);
                break;
                case "list":
                default:
                    $this->renderTestsList($data);
                break;
            }
        ?>
        </div>
        </div>
        <div class='landing-spacer'></div><?php
    }
    /**
     * This function is responsible for listing out HTML links to the available
     * unit tests a user can run
     * @param array $data passed from controller. Its $data['TEST_NAMES']
     *      field should contain an array of all the tests that can be run
     */
    function renderTestsList($data)
    {
        $run_selected_url = "?c=tests&amp;activity=runSelectedTests";
        ?>
        <h2><?=tl('tests_view_test_list')?></h2>
        <p>
        <label for='test-filter'><?=tl('tests_view_filter')?></label>
        <input type='text' id='test-filter' autocomplete='off'
            autofocus value="<?= $data['FILTER'] ?>">
        </p>
        <p>
        <a id='run-selected-link' href='<?=$run_selected_url?>'><?=
            tl('tests_view_run_below_tests')?></a>.
        </p>
        <ul id='test-list' class='square-list'>
        <?php
        foreach ($data['TEST_NAMES'] as $test_name) {
            ?><li><a href='?c=tests&activity=runTest&test=<?=
            $test_name?>'><?=$test_name ?></a></li><?php
        }
        ?>
        </ul>
        <script>
        (function () {
            var filter_input = document.getElementById('test-filter');
            var run_selected = document.getElementById('run-selected-link');
            var run_selected_base = run_selected.getAttribute('href');
            var items = document.querySelectorAll('#test-list li');
            function applyFilter() {
                var needle = filter_input.value.toLowerCase();
                for (var i = 0; i < items.length; i++) {
                    var label = items[i].textContent.toLowerCase();
                    items[i].style.display =
                        (needle === '' || label.indexOf(needle) !== -1)
                            ? '' : 'none';
                }
                run_selected.setAttribute('href', needle === ''
                    ? run_selected_base
                    : run_selected_base + '&filter=' +
                        encodeURIComponent(filter_input.value));
            }
            filter_input.addEventListener('input', applyFilter);
            applyFilter();
        })();
        </script>
        <?php
    }
    /**
     * Uses draw the results of selected unit tests in Yioop
     *
     * @param string $data passed from controller. Its $data['TEST_RESULTS']
     *      field should contain an array of all sthe test results for unit
     *      tests that were carried out
     */
    function renderSelectedTests($data)
    {
        ?><p><a href='?c=tests&activity=listTests'
            >See test case list</a>.</p><?php
        $data['NO_ALL_LINK'] = true;
        foreach ($data['TEST_RESULTS'] as
            $data['TEST_NAME'] => $data['RESULTS']){
            $this->renderTest($data);
        }
    }
    /**
     * Uses draw the results of unit test class, run the tests in it and display
     * the results
     *
     * @param string $data  passed from controller. Its $data['TEST_NAME']
     *      field should contain an array test case results for a particular
     *      unit test. It's $data['NO_ALL_LINK'] should say whether all tests
     *      are currently being run or just one.
     */
    function renderTest($data)
    {
        if (empty($data['NO_ALL_LINK'])) { ?>
            <p><a href='?c=tests&activity=listTests'>See test case list</a>.</p>
            <?php
        }
        $test_title = $data['TEST_NAME'];
        $current_test_url =
            "?c=tests&amp;activity=runTest&amp;test=$test_title";
        $test_title = "<a href='$current_test_url'>$test_title</a>";
        if (!empty($data['METHOD'])) {
            $test_title .= ":" . $data['METHOD'];
        }
        ?>
        <h2><?=$test_title ?></h2><?php
        if (!empty($data['RESULTS']['JS'])) {
            foreach ($data['RESULTS']['DATA'] as
                $test_case_name => $case_data) {
                $method_header = (empty($data['METHOD'])) ?
                    "<a class='hover-link black' ".
                    "href='$current_test_url&method=$test_case_name'>".
                    "$test_case_name</a>" : $test_case_name;
                ?><h3><?= $method_header ?></h3><?php
                echo $case_data;
            }
        } else {
            ?>
            <table class="wikitable">
            <?php
            foreach ($data['RESULTS'] as $test_case_name => $case_time_data) {
                list($case_data, $time_data) = $case_time_data;
                $test_header = (empty($data['METHOD'])) ?
                    "<a class='hover-link black' ".
                    "href='$current_test_url&method=$test_case_name'>".
                    "$test_case_name</a>" : $test_case_name;
                ?><tr><th style='text-align:right'><?= $test_header .
                 "<br><span class='small-font'>(".
                    tl('tests_view_elasped_time') . " " .
                    sprintf("%.5e", $time_data) . "s)" ?></span></th><?php
                $passed = 0;
                $count = 0;
                $failed_items = [];
                foreach ($case_data as $item) {
                    if ($item['PASS']) {
                        $passed++;
                    } else {
                        $failed_items[] = $item;
                    }
                    $count++;
                }
                if ($count == $passed) {
                    $color = "back-light-green";
                } else {
                    $color = "back-red";
                }
                ?><td class='<?=$color?>'><?=$passed?>/<?=$count?> <?=
                    tl('tests_view_tests_passed')?><br><?php
                if (count($failed_items) > 0) {
                    foreach ($failed_items as $item) {
                        echo "  FAILED: ".$item['NAME']."<br>";
                    }
                }
                ?></td></tr><?php
            }
            ?>
            </table>
            <?php
        }
    }
}
