<?php

use Gettext\Translations;
use Gettext\Translation;

    /**
 * Class Language
 *
 * Main multi-language class for cms2
 *
 * @todo scope it. but how?
 */
class Language extends Illuminate\Database\Eloquent\Model {
    public $timestamps = false;
    public static $locale_path = LANGUAGE_LOCALE_PATH;
    public $dirs_that_dont_hold_templates = array('includes','vcs','admin','classes','css','images','.git','js','git','vendor','libs');

        private static function attachReference(Translation $t, ?string $file, ?int $line): void
        {
            if (!$file) {
                return;
            }

            // v4 and older
            if (method_exists($t, 'addReference')) {
                $t->addReference($file, $line);
                return;
            }

            // v5+: getReferences() returns a References bag that has ->add()
            if (method_exists($t, 'getReferences')) {
                $refs = $t->getReferences();
                if (is_object($refs) && method_exists($refs, 'add')) {
                    $refs->add($file, $line);
                    return;
                }
                // extremely defensive fallback
                if (is_array($refs) && method_exists($t, 'setReferences')) {
                    $refs[] = [$file, $line];
                    $t->setReferences($refs);
                }
            }
        }


    public static function isIgnoredPage($page_id) {

        if ( CMS_MULTI_LANG_PAGE_IGNORE !== true ) {
            return false;
        }

        $ignore_json = CMS_MULTI_LANG_PAGE_IGNORE_JSON;
        $ignore_array = json_decode($ignore_json, true);
        if ( empty($ignore_array) ) {
            return false;
        }

        $page_trail = Page::generate_trail($page_id);
        $array_trail = array();
        for ($i=0; $i < count($page_trail); $i++) {
            $array_trail[] = $page_trail[$i]->id;
        }

        $array_trail = array_reverse($array_trail);

        $postfix = "";

        for ($i=0; $i < count($array_trail); $i++) {

            if ( $i > 0 ) {
                $postfix = "/*";
            }

            if ( in_array($array_trail[$i].$postfix, $ignore_array) ) {
                return true;
            } else if ( in_array("!".$array_trail[$i].$postfix, $ignore_array) ) {
                return false;
            }

        }

        if ( in_array("*", $ignore_array) ) {
            return true;
        }

        return false;
    }


    public function iterateThroughTemplates($directory) {
        // create an array to hold directory list
        $results = array();
        $dirs_that_dont_hold_templates = $this->dirs_that_dont_hold_templates;
        foreach(new DirectoryIterator($directory) as $file) {
            if ( (!$file->isDot()) && ($file->getFilename() != basename($_SERVER['PHP_SELF'])) ) {
                if($file->isDir()){
                    if($directory == SITE_PATH && in_array($file->getFilename(), $dirs_that_dont_hold_templates)){
                        continue;
                    }
                    $results = array_merge($results,  $this->iterateThroughTemplates($directory . '/' . $file->getFilename()));
                }else{
                    if($file->getExtension() == 'php' || $file->getExtension() === 'twig'){
                        $file_path = $directory . '/' .  $file->getFilename();
                        $results[] = $file_path;
                    }
                }
            }
        }
        return $results;
    }

    public static function getTranslatables($string, $file = null) {   // ⬅ accept filename too
        $tokens = token_get_all($string);
        $count = count($tokens);
        $bufferFunctions = [];
        $functions = [];
        $translatables = Translations::create();   // ⬅ use static factory

        for ($k = 0; $k < $count; $k++) {
            $value = $tokens[$k];

            if (is_string($value)) {
                if ($value === ')' && isset($bufferFunctions[0])) {
                    $functions[] = array_shift($bufferFunctions);
                }
                continue;
            }

            if (isset($bufferFunctions[0]) && ($value[0] === T_CONSTANT_ENCAPSED_STRING)) {
                $val = $value[1];
                $val = ($val[0] === '"') ? str_replace('\\"', '"', $val)
                    : str_replace("\\'", "'", $val);
                $bufferFunctions[0][2][] = substr($val, 1, -1);
                continue;
            }

            // SAFER lookahead
            if (($value[0] === T_STRING) && isset($tokens[$k + 1]) && is_string($tokens[$k + 1]) && ($tokens[$k + 1] === '(')) {
                array_unshift($bufferFunctions, [$value[1], $value[2], []]);
                $k++;
                continue;
            }
        }

        foreach ($functions as $function) {
            [$name, $line, $args] = $function;

            switch ($name) {
                case '_':
                case '__':
                case 'gettext':
                    if (!isset($args[0])) { continue 2; }
                    $t = Translation::create('', $args[0]);
                    self::attachReference($t, $file, $line);
                    $translatables->add($t);
                    break;

                case 'n__':
                    if (!isset($args[1])) { continue 2; }
                    $t = Translation::create('', $args[0], $args[1]);
                    self::attachReference($t, $file, $line);
                    $translatables->add($t);
                    break;

                case 'p__':
                    if (!isset($args[1])) { continue 2; }
                    $t = Translation::create($args[0], $args[1]);
                    self::attachReference($t, $file, $line);
                    $translatables->add($t);
                    break;
            }
        }
        return $translatables;
    }
}
