<?php

namespace FormGent\WhichBrowser\Analyser\Header\Useragent\Device;

use FormGent\WhichBrowser\Constants;
use FormGent\WhichBrowser\Data;
trait Television
{
    private function detectTelevision($ua)
    {
        /* Detect the type based on some common markers */
        $this->detectGenericTelevision($ua);
        /* Try to parse some generic methods to store device information */
        $this->detectGenericTelevisionModels($ua);
        $this->detectGenericInettvBrowser($ua);
        $this->detectGenericHbbTV($ua);
        /* Look for specific manufacturers and models */
        $this->detectPanasonicTelevision($ua);
        $this->detectSharpTelevision($ua);
        $this->detectSamsungTelevision($ua);
        $this->detectSonyTelevision($ua);
        $this->detectPhilipsTelevision($ua);
        $this->detectLgTelevision($ua);
        $this->detectToshibaTelevision($ua);
        $this->detectSanyoTelevision($ua);
        /* Try to detect set top boxes from various manufacturers */
        $this->detectSettopboxes($ua);
        /* Improve model names */
        $this->improveModelsOnDeviceTypeTelevision();
    }
    /* Generic markers */
    private function detectGenericTelevision($ua)
    {
        if (\preg_match('/CE-HTML/u', $ua)) {
            $this->data->device->type = Constants\DeviceType::TELEVISION;
        }
        if (\preg_match('/SmartTvA\\//u', $ua)) {
            $this->data->device->type = Constants\DeviceType::TELEVISION;
        }
        if (\preg_match('/NETRANGEMMH/u', $ua)) {
            $this->data->device->type = Constants\DeviceType::TELEVISION;
        }
    }
    /* Toshiba */
    private function detectToshibaTelevision($ua)
    {
        if (\preg_match('/Toshiba_?TP\\//u', $ua) || \preg_match('/TSBNetTV ?\\//u', $ua)) {
            $this->data->device->manufacturer = 'Toshiba';
            $this->data->device->series = 'Smart TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
        if (\preg_match('/TOSHIBA;[^;]+;([A-Z]+[0-9]+[A-Z]+);/u', $ua, $match)) {
            $this->data->device->manufacturer = 'Toshiba';
            $this->data->device->model = $match[1];
            $this->data->device->series = 'Smart TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
    }
    /* LG */
    private function detectLgTelevision($ua)
    {
        if (\preg_match('/(LGSmartTV|LG smartTV)/u', $ua)) {
            $this->data->device->manufacturer = 'LG';
            $this->data->device->series = 'Smart TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
        if (\preg_match('/UPLUSTVBROWSER/u', $ua)) {
            $this->data->device->manufacturer = 'LG';
            $this->data->device->series = 'U+ tv';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
        /* NetCast */
        if (\preg_match('/LG NetCast\\.(TV|Media)-([0-9]*)/u', $ua, $match)) {
            $this->data->device->manufacturer = 'LG';
            $this->data->device->series = 'NetCast ' . $match[1] . ' ' . $match[2];
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/LG Browser\\/[0-9.]+\\([^;]+; LGE; ([^;]+);/u', $ua, $match)) {
                if (\substr($match[1], 0, 6) != 'GLOBAL' && \substr($match[1], 0, 7) != 'NETCAST') {
                    $this->data->device->model = $match[1];
                }
            }
        }
        /* NetCast */
        if ($ua == "Mozilla/5.0 (X11; Linux; ko-KR) AppleWebKit/534.26+ (KHTML, like Gecko) Version/5.0 Safari/534.26+" || $ua == "Mozilla/5.0 (DirectFB; Linux; ko-KR) AppleWebKit/534.26 (KHTML, like Gecko) Version/5.0 Safari/534.26" || $ua == "Mozilla/5.0 (DirectFB; Linux; ko-KR) AppleWebKit/534.26+ (KHTML, like Gecko) Version/5.0 Safari/534.26+") {
            $this->data->device->manufacturer = 'LG';
            $this->data->device->series = 'NetCast TV 2012';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
        /* NetCast or WebOS */
        if (\preg_match('/NetCast/u', $ua) && \preg_match('/SmartTV\\/([0-9])/u', $ua, $match)) {
            $this->data->device->manufacturer = 'LG';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\intval($match[1]) < 5) {
                $this->data->device->series = 'NetCast TV';
            } else {
                $this->data->device->series = 'webOS TV';
                $this->data->os->reset(['name' => 'webOS', 'hidden' => \true]);
            }
        }
        /* WebOS */
        if (\preg_match('/Web[O0]S/u', $ua) && \preg_match('/Large Screen/u', $ua)) {
            $this->data->device->manufacturer = 'LG';
            $this->data->device->series = 'webOS TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->os->reset(['name' => 'webOS', 'hidden' => \true]);
        }
        if (\preg_match('/Web[O0]S; Linux\\/SmartTV/u', $ua)) {
            $this->data->device->manufacturer = 'LG';
            $this->data->device->series = 'webOS TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->os->reset(['name' => 'webOS', 'hidden' => \true]);
        }
        if (\preg_match('/webOS\\.TV-([0-9]+)/u', $ua, $match)) {
            $this->data->device->manufacturer = 'LG';
            $this->data->device->series = 'webOS TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/LG Browser\\/[0-9.]+\\(LGE; ([^;]+);/u', $ua, $match)) {
                if (\strtoupper(\substr($match[1], 0, 5)) != 'WEBOS') {
                    $this->data->device->model = $match[1];
                }
            }
            $this->data->os->reset(['name' => 'webOS', 'hidden' => \true]);
        }
        if (\preg_match('/PBRM\\//u', $ua)) {
            $this->data->browser->name = "Pro:Centric";
            $this->data->browser->version = null;
            $this->data->device->manufacturer = 'LG';
            $this->data->device->series = 'webOS TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/PBRM\\/[0-9.]+ \\( ;LGE ;([^;]+) ;/u', $ua, $match)) {
                if (\strtoupper(\substr($match[1], 0, 5)) != 'WEBOS') {
                    $this->data->device->model = $match[1];
                }
            }
            $this->data->os->reset(['name' => 'webOS', 'hidden' => \true]);
        }
    }
    /* Philips */
    private function detectPhilipsTelevision($ua)
    {
        if (\preg_match('/NETTV\\//u', $ua)) {
            $this->data->device->manufacturer = 'Philips';
            $this->data->device->series = 'Net TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/AquosTV/u', $ua)) {
                $this->data->device->manufacturer = 'Sharp';
                $this->data->device->series = 'Aquos TV';
            }
            if (\preg_match('/BANGOLUFSEN/u', $ua)) {
                $this->data->device->manufacturer = 'Bang & Olufsen';
                $this->data->device->series = 'Smart TV';
            }
            if (\preg_match('/PHILIPS-AVM/u', $ua)) {
                $this->data->device->series = 'Blu-ray Player';
            }
        }
        if (\preg_match('/PHILIPS_OLS_20[0-9]+/u', $ua)) {
            $this->data->device->manufacturer = 'Philips';
            $this->data->device->series = 'Net TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
    }
    /* Sony */
    private function detectSonyTelevision($ua)
    {
        if (\preg_match('/SonyCEBrowser/u', $ua)) {
            $this->data->device->manufacturer = 'Sony';
            $this->data->device->series = 'Smart TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/SonyCEBrowser\\/[0-9.]+ \\((?:BDPlayer; |DTV[0-9]+\\/)?([^;_]+)/u', $ua, $match)) {
                if ($match[1] != 'ModelName') {
                    $this->data->device->model = $match[1];
                }
            }
        }
        if (\preg_match('/SonyDTV/u', $ua)) {
            $this->data->device->manufacturer = 'Sony';
            $this->data->device->series = 'Smart TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/(KDL-?[0-9]+[A-Z]+[0-9]+)/u', $ua, $match)) {
                $this->data->device->model = $match[1];
                $this->data->device->generic = \false;
            }
            if (\preg_match('/(XBR-?[0-9]+[A-Z]+[0-9]+)/u', $ua, $match)) {
                $this->data->device->model = $match[1];
                $this->data->device->generic = \false;
            }
        }
        if (\preg_match('/SonyBDP/u', $ua)) {
            $this->data->device->manufacturer = 'Sony';
            $this->data->device->series = "Blu-ray Player";
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
        if (\preg_match('/SmartBD/u', $ua) && \preg_match('/(BDP-[A-Z][0-9]+)/u', $ua, $match)) {
            $this->data->device->manufacturer = 'Sony';
            $this->data->device->model = $match[1];
            $this->data->device->series = 'Blu-ray Player';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
        if (\preg_match('/\\s+([0-9]+)BRAVIA/u', $ua, $match)) {
            $this->data->device->manufacturer = 'Sony';
            $this->data->device->model = 'Bravia';
            $this->data->device->series = 'Smart TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
    }
    /* Samsung */
    private function detectSamsungTelevision($ua)
    {
        if (\preg_match('/(SMART-TV;|SmartHub;)/u', $ua)) {
            $this->data->device->manufacturer = 'Samsung';
            $this->data->device->series = 'Smart TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/Linux\\/SmartTV\\+([0-9]*)/u', $ua, $match)) {
                $this->data->device->series = 'Smart TV ' . $match[1];
            } elseif (\preg_match('/Maple([0-9]*)/u', $ua, $match)) {
                $this->data->device->series = 'Smart TV ' . $match[1];
            }
        }
        if (\preg_match('/Maple_?([0-9][0-9][0-9][0-9])/u', $ua, $match)) {
            $this->data->device->manufacturer = 'Samsung';
            $this->data->device->series = 'Smart TV ' . $match[1];
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/Linux\\/(?:SmartTV)?\\+([0-9]{4,4})/u', $ua, $match)) {
                $this->data->device->series = 'Smart TV ' . $match[1];
            }
        }
        if (\preg_match('/Maple ([0-9]+\\.[0-9]+)\\.[0-9]+/u', $ua, $match)) {
            $this->data->device->manufacturer = 'Samsung';
            $this->data->device->series = 'Smart TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            switch ($match[1]) {
                case '5.0':
                    $this->data->device->series = 'Smart TV 2009';
                    break;
                case '5.1':
                    $this->data->device->series = 'Smart TV 2010';
                    break;
                case '6.0':
                    $this->data->device->series = 'Smart TV 2011';
                    break;
            }
        }
        if (\preg_match('/Model\\/Samsung-(BD-[A-Z][0-9]+)/u', $ua, $match)) {
            $this->data->device->manufacturer = 'Samsung';
            $this->data->device->model = $match[1];
            $this->data->device->series = 'Blu-ray Player';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
        if (\preg_match('/olleh tv;/u', $ua)) {
            $this->data->device->manufacturer = 'Samsung';
            $this->data->device->model = null;
            $this->data->device->series = null;
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/(SMT-[A-Z0-9]+)/u', $ua, $match)) {
                $this->data->device->model = $match[1];
                $this->data->device->identifier = $match[1];
                $this->data->device->generic = \false;
            }
            if ($this->data->device->model == "SMT-E5015") {
                $this->data->device->model = 'Olleh SkyLife Smart Settopbox';
            }
        }
    }
    /* Sanyo */
    private function detectSanyoTelevision($ua)
    {
        if (\preg_match('/Aplix_SANYO_browser/u', $ua)) {
            $this->data->device->manufacturer = 'Sanyo';
            $this->data->device->series = 'Internet TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
    }
    /* Sharp */
    private function detectSharpTelevision($ua)
    {
        if (\preg_match('/(AQUOSBrowser|AQUOS-(AS|DMP))/u', $ua)) {
            $this->data->device->manufacturer = 'Sharp';
            $this->data->device->series = 'Aquos TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/LC\\-([0-9]+[A-Z]+[0-9]+[A-Z]+)/u', $ua, $match)) {
                $this->data->device->model = $match[1];
                $this->data->device->generic = \false;
            }
        }
    }
    /* Panasonic */
    private function detectPanasonicTelevision($ua)
    {
        if (\preg_match('/Viera/u', $ua)) {
            $this->data->device->manufacturer = 'Panasonic';
            $this->data->device->series = 'Viera';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/Panasonic\\.tv\\.(?:mid\\.|pro4\\.)?([0-9]+)/u', $ua, $match)) {
                $this->data->device->series = 'Viera ' . $match[1];
            }
            if (\preg_match('/\\(Panasonic, ([0-9]+),/u', $ua, $match)) {
                $this->data->device->series = 'Viera ' . $match[1];
            }
            if (\preg_match('/Viera\\; rv\\:34/u', $ua, $match)) {
                $this->data->device->series = 'Viera 2015';
            }
        }
        if (\preg_match('/; Diga;/u', $ua)) {
            $this->data->device->manufacturer = 'Panasonic';
            $this->data->device->series = 'Diga';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
    }
    /* Various set top boxes */
    private function detectSettopboxes($ua)
    {
        if (!\preg_match('/(lacleTV|LOEWE|KreaTV|ADB|Mstar|TechniSat|Technicolor|Highway|CiscoBrowser|Sunniwell|Enseo|LocationFreeTV|Winbox|DuneHD|Roku|AppleTV|Apple TV|WebTV|OpenTV|MediStream)/ui', $ua)) {
            return;
        }
        /* Orange La clé TV */
        if (\preg_match('/lacleTV\\//u', $ua)) {
            $this->data->device->manufacturer = 'Orange';
            $this->data->device->series = 'La clé TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
        /* Loewe */
        if (\preg_match('/LOEWE\\/TV/u', $ua)) {
            $this->data->device->manufacturer = 'Loewe';
            $this->data->device->series = 'Smart TV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/((?:SL|ID)[0-9]+)/u', $ua, $match)) {
                $this->data->device->model = $match[1];
            }
        }
        /* KreaTV */
        if (\preg_match('/KreaTV/u', $ua)) {
            $this->data->os->reset();
            $this->data->device->series = 'KreaTV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->device->generic = \false;
            if (\preg_match('/Motorola/u', $ua)) {
                $this->data->device->manufacturer = 'Motorola';
            }
        }
        /* ADB */
        if (\preg_match('/\\(ADB; ([^\\)]+)\\)/u', $ua, $match)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'ADB';
            $this->data->device->model = ($match[1] != 'Unknown' ? \str_replace('ADB', '', $match[1]) . ' ' : '') . 'IPTV receiver';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->device->generic = \false;
        }
        /* MStar */
        if (\preg_match('/Mstar;/u', $ua)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'MStar';
            $this->data->device->model = 'PVR';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
        /* TechniSat */
        if (\preg_match('/TechniSat ([^;]+);/u', $ua, $match)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'TechniSat';
            $this->data->device->model = $match[1];
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->device->generic = \false;
        }
        /* Technicolor */
        if (\preg_match('/Technicolor_([^;]+);/u', $ua, $match)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'Technicolor';
            $this->data->device->model = $match[1];
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->device->generic = \false;
        }
        /* Cisco MediaHighway */
        if (\preg_match('/(Media-Highway Evolution|CiscoBrowser\\/CI)/u', $ua, $match)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'Cisco';
            $this->data->device->model = 'MediaHighway';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->device->generic = \false;
        }
        /* Sunniwell */
        if (\preg_match('/Sunniwell/u', $ua) && \preg_match('/Resolution/u', $ua)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'Sunniwell';
            $this->data->device->series = 'STB';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->device->generic = \false;
        }
        /* Enseo */
        if (\preg_match('/Enseo\\/([A-Z0-9]+)/u', $ua, $match)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'Enseo';
            $this->data->device->model = $match[1];
            $this->data->device->series = 'STB';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->device->generic = \false;
        }
        /* Sony LocationFreeTV */
        if (\preg_match('/LocationFreeTV\\/([A-Z0-9\\-]+)/u', $ua, $match)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'Sony';
            $this->data->device->model = 'LocationFreeTV ' . $match[1];
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->device->generic = \false;
        }
        /* Winbox Evo2 */
        if (\preg_match('/Winbox Evo2/u', $ua)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'Winbox';
            $this->data->device->model = 'Evo2';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->device->generic = \false;
        }
        /* DuneHD */
        if (\preg_match('/DuneHD\\//u', $ua)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'Dune HD';
            $this->data->device->model = '';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            if (\preg_match('/DuneHD\\/[0-9.]+ \\(([^;]+);/u', $ua, $match)) {
                $this->data->device->model = $match[1];
            }
        }
        /* Roku  */
        if (\preg_match('/Roku(?:([0-9]+)[A-Z]+)?\\/DVP-(?:([0-9]+)[A-Z]+-)?[0-9\\.]+/u', $ua, $match)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'Roku';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $models = ['2000' => 'HD', '2050' => 'XD', '2100' => 'XDS', '2400' => 'LT', '2450' => 'LT', '2500' => 'HD', '2700' => 'LT', '2710' => '1 SE', '2720' => '2', '3000' => '2 HD', '3050' => '2 XD', '3100' => '2 XS', '3400' => 'Streaming Stick, MHL', '3420' => 'Streaming Stick, MHL', '3500' => 'Streaming Stick, HDMI', '3600' => 'Streaming Stick', '3700' => 'Express', '3710' => 'Express+', '3800' => 'Streaming Stick', '3810' => 'Streaming Stick+', '3900' => 'Express', '3910' => 'Express+', '3920' => 'Premiere', '3921' => 'Premiere+', '3930' => 'Express', '3931' => 'Express+', '4200' => '3', '4210' => '2', '4230' => '3', '4400' => '4', '4620' => 'Premiere', '4630' => 'Premiere+', '4640' => 'Ultra', '4660' => 'Ultra', '4661' => 'Ultra', '4662' => 'Ultra LT', '4670' => 'Ultra', '4800' => 'Ultra'];
            if (!empty($match[1]) || !empty($match[2])) {
                $model = !empty($match[1]) ? $match[1] : $match[2];
                if (isset($models[$model])) {
                    $this->data->device->model = $models[$model];
                    $this->data->device->generic = \false;
                }
            }
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
        if (\preg_match('/Roku\\/DVP-[0-9\\.]+ \\(([0-9A-Z]{2,2})[0-9]+\\./u', $ua, $match)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'Roku';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $models = ['02' => '2 XS', '03' => 'LT', '04' => '3', '07' => 'LT', '09' => 'Streaming Stick', '29' => 'Ultra', '30' => ['TCL', '4K Roku TV'], '51' => 'Express', 'AE' => 'Express'];
            if (!empty($match[1])) {
                $model = $match[1];
                if (isset($models[$model])) {
                    if (\is_array($models[$model])) {
                        $this->data->device->manufacturer = $models[$model][0];
                        $this->data->device->model = $models[$model][1];
                    } else {
                        $this->data->device->model = $models[$model];
                    }
                    $this->data->device->generic = \false;
                }
            }
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
        if (\preg_match('/\\(Roku/u', $ua)) {
            $this->data->device->manufacturer = 'Roku';
            $this->data->device->model = '';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
        }
        /* AppleTV */
        if (\preg_match('/Apple ?TV/u', $ua)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'Apple';
            $this->data->device->model = 'AppleTV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->device->generic = \false;
        }
        /* WebTV */
        if (\preg_match('/WebTV\\/[0-9.]/u', $ua)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'Microsoft';
            $this->data->device->model = 'WebTV';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->device->generic = \false;
        }
        /* MediStream */
        if (\preg_match('/MediStream/u', $ua)) {
            $this->data->os->reset();
            $this->data->device->manufacturer = 'Bewatec';
            $this->data->device->model = 'MediStream';
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::MATCH_UA;
            $this->data->device->generic = \false;
        }
    }
    /* Generic model information */
    private function detectGenericTelevisionModels($ua)
    {
        if (\preg_match('/\\(([^,\\(]+),\\s*([^,\\(]+),\\s*(?:[Ww]ired|[Ww]ireless)\\)/u', $ua, $match)) {
            $vendorName = Data\Manufacturers::identify(Constants\DeviceType::TELEVISION, $match[1]);
            $modelName = \trim($match[2]);
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $this->data->device->identified |= Constants\Id::PATTERN;
            if (!isset($this->data->device->series)) {
                $this->data->device->series = 'Smart TV';
            }
            switch ($vendorName) {
                case 'ARRIS':
                    $this->data->device->manufacturer = 'Arris';
                    $this->data->device->model = $modelName;
                    break;
                case 'LG':
                    $this->data->device->manufacturer = 'LG';
                    switch ($modelName) {
                        case 'WEBOS1':
                        case 'webOS.TV':
                            $this->data->device->series = 'webOS TV';
                            break;
                        case 'NETCAST4':
                        case 'NetCast4.0':
                        case 'GLOBAL-PLAT4':
                            $this->data->device->series = 'NetCast TV 2013';
                            break;
                        default:
                            $this->data->device->model = $modelName;
                            break;
                    }
                    break;
                case 'Google Fiber':
                    $this->data->device->manufacturer = $vendorName;
                    $this->data->device->model = 'TV Box';
                    break;
                case 'Sagemcom':
                    $this->data->device->manufacturer = $vendorName;
                    $this->data->device->series = 'Settopbox';
                    if (\preg_match('/^([A-Z]+[0-9]+)/ui', $modelName, $match)) {
                        $this->data->device->model = $match[1];
                        unset($this->data->device->series);
                    }
                    break;
                case 'TiVo':
                    $this->data->device->manufacturer = 'TiVo';
                    $this->data->device->series = 'DVR';
                    break;
                default:
                    $this->data->device->manufacturer = $vendorName;
                    if (!\in_array($modelName, ['dvb'])) {
                        $this->data->device->model = $modelName;
                    }
                    break;
            }
        }
    }
    /* InettvBrowser model information */
    private function detectGenericInettvBrowser($ua)
    {
        if (\preg_match('/(?:DTVNetBrowser|InettvBrowser|Hybridcast)\\/[0-9\\.]+[A-Z]? ?\\(/u', $ua, $match)) {
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $vendorName = null;
            $modelName = null;
            $found = \false;
            if (\preg_match('/(?:DTVNetBrowser|InettvBrowser)\\/[0-9\\.]+[A-Z]? ?\\(([^;]*)\\s*;\\s*([^;]*)\\s*;/u', $ua, $match)) {
                $vendorName = \trim($match[1]);
                $modelName = \trim($match[2]);
                $found = \true;
            }
            if (\preg_match('/Hybridcast\\/[0-9\\.]+ ?\\([^;]*;([^;]*)\\s*;\\s*([^;]*)\\s*;/u', $ua, $match)) {
                $vendorName = \trim($match[1]);
                $modelName = \trim($match[2]);
                $found = \true;
            }
            if ($found) {
                $this->data->device->identified |= Constants\Id::PATTERN;
                $data = ['0003D5' => 'Advanced Communications', '000024' => 'Connect AS', '000087' => 'Hitachi', '00A0B0' => 'I-O Data Device', '00E091' => 'LG', '0050C9' => 'Maspro Denkoh', '002692' => 'Mitsubishi', '38E08E' => 'Mitsubishi', '008045' => 'Panasonic', '00E036' => 'Pioneer', '00E064' => 'Samsung', '08001F' => 'Sharp', '00014A' => 'Sony', '000039' => 'Toshiba'];
                if (isset($data[$vendorName])) {
                    $this->data->device->manufacturer = $data[$vendorName];
                    if ($this->data->device->manufacturer == 'LG') {
                        switch ($modelName) {
                            case 'LGE2D2012M':
                                $this->data->device->series = 'NetCast TV 2012';
                                break;
                            case 'LGE3D2012M':
                                $this->data->device->series = 'NetCast TV 2012';
                                break;
                            case 'LGwebOSTV':
                            case 'webOSTV3_0':
                                $this->data->device->series = 'webOS TV';
                                break;
                        }
                    }
                    if ($this->data->device->manufacturer == 'Panasonic') {
                        if (\substr($modelName, 0, 6) != 'PANATV') {
                            $this->data->device->model = $modelName;
                        }
                    }
                }
                if (!isset($this->data->device->series)) {
                    $this->data->device->series = 'Smart TV';
                }
            }
        }
    }
    /* HbbTV model information */
    private function detectGenericHbbTV($ua)
    {
        if (\preg_match('/((HbbTV|OHTV|SmartTV)\\/[0-9\\.]+|CE-HTML)/iu', $ua)) {
            $this->data->device->type = Constants\DeviceType::TELEVISION;
            $vendorName = null;
            $modelName = null;
            $found = \false;
            if (\preg_match('/HbbTV\\/[0-9\\.]+;CE-HTML\\/[0-9\\.]+;([A-Z]+)\\s([^;]+);/iu', $ua, $match)) {
                $vendorName = Data\Manufacturers::identify(Constants\DeviceType::TELEVISION, $match[1]);
                $modelName = \trim($match[2]);
                $found = \true;
            }
            if (\preg_match('/UID\\([a-f0-9:]+\\/([^\\/]+)\\/([^\\/]+)\\/[0-9a-z\\.]+\\)\\+CE-HTML/iu', $ua, $match)) {
                $vendorName = Data\Manufacturers::identify(Constants\DeviceType::TELEVISION, $match[2]);
                $modelName = \trim($match[1]);
                $found = \true;
            }
            if (\preg_match('/(?:HbbTV|OHTV)\\/[0-9\\.]+ \\(([^;]*);\\s*([^;]*)\\s*;\\s*([^;]*)\\s*;/u', $ua, $match)) {
                if (\trim($match[1]) == "" || \in_array(\strtok($match[1], ' '), ['PVR', 'DL']) || \strpos($match[1], '+') !== \false) {
                    $vendorName = Data\Manufacturers::identify(Constants\DeviceType::TELEVISION, $match[2]);
                    $modelName = \trim($match[3]);
                } else {
                    $vendorName = Data\Manufacturers::identify(Constants\DeviceType::TELEVISION, $match[1]);
                    $modelName = \trim($match[2]);
                }
                $found = \true;
            }
            if (\preg_match('/(?:^|\\s)SmartTV\\/[0-9\\.]+ \\(([^;]*)\\s*;\\s*([^;]*)\\s*;/u', $ua, $match)) {
                $vendorName = Data\Manufacturers::identify(Constants\DeviceType::TELEVISION, $match[1]);
                $modelName = \trim($match[2]);
                $found = \true;
            }
            if (\in_array($vendorName, ['Access', 'ANT', 'EMSYS', 'Em-Sys', 'Ocean Blue Software', 'Opera', 'Opera Software', 'Seraphic', 'ST', 'Vendor'])) {
                $found = \false;
            }
            if ($found) {
                $this->data->device->identified |= Constants\Id::PATTERN;
                switch ($vendorName) {
                    case 'LG':
                        $this->data->device->manufacturer = 'LG';
                        switch ($modelName) {
                            case 'NetCast 3.0':
                            case 'GLOBAL_PLAT3':
                                $this->data->device->series = 'NetCast TV 2012';
                                break;
                            case 'NetCast 4.0':
                            case 'GLOBAL-PLAT4':
                                $this->data->device->series = 'NetCast TV 2013';
                                break;
                            case 'WEBOS1':
                            case 'WEBOS2.0':
                            case 'WEBOS3':
                                $this->data->device->series = 'webOS TV';
                                break;
                        }
                        break;
                    case 'Samsung':
                        $this->data->device->manufacturer = 'Samsung';
                        switch ($modelName) {
                            case 'SmartTV2012':
                                $this->data->device->series = 'Smart TV 2012';
                                break;
                            case 'SmartTV2013':
                                $this->data->device->series = 'Smart TV 2013';
                                break;
                            case 'SmartTV2014':
                                $this->data->device->series = 'Smart TV 2014';
                                break;
                            case 'SmartTV2015':
                                $this->data->device->series = 'Smart TV 2015';
                                break;
                            case 'SmartTV2016':
                                $this->data->device->series = 'Smart TV 2016';
                                break;
                            case 'SmartTV2017':
                                $this->data->device->series = 'Smart TV 2017';
                                break;
                            case 'OTV-SMT-E5015':
                                $this->data->device->model = 'Olleh SkyLife Smart Settopbox';
                                unset($this->data->device->series);
                                break;
                        }
                        break;
                    case 'Panasonic':
                        $this->data->device->manufacturer = 'Panasonic';
                        switch ($modelName) {
                            case 'VIERA 2011':
                                $this->data->device->series = 'Viera 2011';
                                break;
                            case 'VIERA 2012':
                                $this->data->device->series = 'Viera 2012';
                                break;
                            case 'VIERA 2013':
                                $this->data->device->series = 'Viera 2013';
                                break;
                            case 'VIERA 2014':
                                $this->data->device->series = 'Viera 2014';
                                break;
                            case 'VIERA 2015':
                            case 'Viera2015.mid':
                                $this->data->device->series = 'Viera 2015';
                                break;
                            case 'VIERA 2016':
                                $this->data->device->series = 'Viera 2016';
                                break;
                            case 'VIERA 2017':
                                $this->data->device->series = 'Viera 2017';
                                break;
                            case 'SmartTV2018mid':
                                $this->data->device->series = 'Viera 2018';
                                break;
                            default:
                                $this->data->device->model = $modelName;
                                if (\substr($modelName, 0, 4) == 'DIGA') {
                                    $this->data->device->series = 'Diga';
                                    $this->data->device->model = null;
                                }
                                break;
                        }
                        break;
                    case 'TV2N':
                        $this->data->device->manufacturer = 'TV2N';
                        switch ($modelName) {
                            case 'videoweb':
                                $this->data->device->model = 'Videoweb';
                                break;
                        }
                        break;
                    default:
                        if ($vendorName != '' && !\in_array($vendorName, ['OEM', 'vendorName'])) {
                            $this->data->device->manufacturer = $vendorName;
                        }
                        if ($modelName != '' && !\in_array($modelName, ['dvb', 'modelName', 'undefined-model-name', 'N/A'])) {
                            $this->data->device->model = $modelName;
                        }
                        break;
                }
                switch ($modelName) {
                    case 'hdr1000s':
                        $this->data->device->manufacturer = 'Humax';
                        $this->data->device->model = 'HDR-1000S';
                        $this->data->device->identified |= Constants\Id::MATCH_UA;
                        $this->data->device->generic = \false;
                        break;
                    case 'hdr4000t':
                        $this->data->device->manufacturer = 'Humax';
                        $this->data->device->model = 'HDR-4000T';
                        $this->data->device->identified |= Constants\Id::MATCH_UA;
                        $this->data->device->generic = \false;
                        break;
                    case 'hgs1000s':
                        $this->data->device->manufacturer = 'Humax';
                        $this->data->device->model = 'HGS-1000S';
                        $this->data->device->identified |= Constants\Id::MATCH_UA;
                        $this->data->device->generic = \false;
                        break;
                    case 'hms1000s':
                    case 'hms1000sph2':
                        $this->data->device->manufacturer = 'Humax';
                        $this->data->device->model = 'HMS-1000S';
                        $this->data->device->identified |= Constants\Id::MATCH_UA;
                        $this->data->device->generic = \false;
                        break;
                }
            }
        }
        if (\preg_match('/HbbTV\\/[0-9.]+;CE-HTML\\/[0-9.]+;([^\\s;]+)\\s[^\\s;]+;/u', $ua, $match)) {
            $this->data->device->manufacturer = Data\Manufacturers::identify(Constants\DeviceType::TELEVISION, $match[1]);
            if (!isset($this->data->device->series)) {
                $this->data->device->series = 'Smart TV';
            }
        }
        if (\preg_match('/HbbTV\\/[0-9.]+;CE-HTML\\/[0-9.]+;Vendor\\/([^\\s;]+);/u', $ua, $match)) {
            $this->data->device->manufacturer = Data\Manufacturers::identify(Constants\DeviceType::TELEVISION, $match[1]);
            if (!isset($this->data->device->series)) {
                $this->data->device->series = 'Smart TV';
            }
        }
    }
    /* Try to reformat some of the detected generic models */
    private function improveModelsOnDeviceTypeTelevision()
    {
        if ($this->data->device->type != Constants\DeviceType::TELEVISION) {
            return;
        }
        if (isset($this->data->device->model) && isset($this->data->device->manufacturer)) {
            if ($this->data->device->manufacturer == 'Dune HD') {
                if (\preg_match('/tv([0-9]+[a-z]?)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = 'TV-' . \strtoupper($match[1]);
                }
                if ($this->data->device->model == 'connect') {
                    $this->data->device->model = 'Connect';
                }
            }
            if ($this->data->device->manufacturer == 'Humax') {
                $this->data->device->series = "Digital Receiver";
            }
            if ($this->data->device->manufacturer == 'Inverto') {
                if (\preg_match('/IDL[ -]?([0-9]+.*)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = 'IDL ' . $match[1];
                }
                if (\preg_match('/MBN([0-9]+)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = 'MBN ' . $match[1];
                }
            }
            if ($this->data->device->manufacturer == 'HyperPanel') {
                $this->data->device->model = \strtok(\strtoupper($this->data->device->model), ' ');
            }
            if ($this->data->device->manufacturer == 'LG') {
                if (\preg_match('/(?:ATSC|DVB)-(.*)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = $match[1];
                    $this->data->device->generic = \false;
                }
                if (\preg_match('/[0-9][0-9]([A-Z][A-Z][0-9][0-9][0-9][0-9A-Z])/u', $this->data->device->model, $match)) {
                    $this->data->device->model = $match[1];
                    $this->data->device->generic = \false;
                }
                if (\preg_match('/Media\\/(.*)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = $match[1];
                    $this->data->device->generic = \false;
                }
            }
            if ($this->data->device->manufacturer == 'Loewe') {
                $this->data->device->series = 'Smart TV';
                if (\preg_match('/((?:ID|SL)[0-9]+)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = 'Connect ' . $match[1];
                    $this->data->device->generic = \false;
                }
            }
            if ($this->data->device->manufacturer == 'Philips') {
                if (\preg_match('/[0-9][0-9]([A-Z][A-Z][A-Z][0-9][0-9][0-9][0-9])/u', $this->data->device->model, $match)) {
                    $this->data->device->model = $match[1];
                    $this->data->device->generic = \false;
                }
                if (\preg_match('/(MT[0-9]+)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = $match[1];
                    $this->data->device->series = "Digital Receiver";
                    $this->data->device->generic = \false;
                }
                if (\preg_match('/(BDP[0-9]+)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = $match[1];
                    $this->data->device->series = "Blu-ray Player";
                    $this->data->device->generic = \false;
                }
            }
            if ($this->data->device->manufacturer == 'Toshiba') {
                if (\preg_match('/DTV_(.*)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = 'Regza ' . $match[1];
                    $this->data->device->generic = \false;
                }
                if (\preg_match('/[0-9][0-9]([A-Z][A-Z][0-9][0-9][0-9])/u', $this->data->device->model, $match)) {
                    $this->data->device->model = 'Regza ' . $match[1];
                    $this->data->device->generic = \false;
                }
                if (\preg_match('/[0-9][0-9](ZL[0-9])/u', $this->data->device->model, $match)) {
                    $this->data->device->model = $match[1] . ' Cevo';
                    $this->data->device->generic = \false;
                }
                if (\preg_match('/(BDX[0-9]+)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = $match[1];
                    $this->data->device->series = "Blu-ray Player";
                    $this->data->device->generic = \false;
                }
            }
            if ($this->data->device->manufacturer == 'Selevision') {
                $this->data->device->model = \str_replace('Selevision ', '', $this->data->device->model);
            }
            if ($this->data->device->manufacturer == 'Sharp') {
                if (\preg_match('/[0-9][0-9]([A-Z]+[0-9]+[A-Z]+)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = $match[1];
                    $this->data->device->generic = \false;
                }
            }
            if ($this->data->device->manufacturer == 'Sony') {
                if (\preg_match('/(BDP[0-9]+G)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = $match[1];
                    $this->data->device->series = "Blu-ray Player";
                    $this->data->device->generic = \false;
                }
                if (\preg_match('/KDL?-?[0-9]*([A-Z]+[0-9]+)[A-Z]*/u', $this->data->device->model, $match)) {
                    $this->data->device->model = 'Bravia ' . $match[1];
                    $this->data->device->series = 'Smart TV';
                    $this->data->device->generic = \false;
                }
            }
            if ($this->data->device->manufacturer == 'Pioneer') {
                if (\preg_match('/(BDP-[0-9]+)/u', $this->data->device->model, $match)) {
                    $this->data->device->model = $match[1];
                    $this->data->device->series = "Blu-ray Player";
                    $this->data->device->generic = \false;
                }
            }
        }
    }
}
