<?php
/**
 * Turkish Domain Whois Handler (.tr and .com.tr)
 *
 * This handler processes whois data for Turkish domains (.tr, .com.tr, .net.tr, etc.)
 * Current whois server: whois.trabis.gov.tr
 *
 * @package WhoisHandler
 * @version 2.0
 */

if (!defined('__TR_HANDLER__')) {
    define('__TR_HANDLER__', 1);
}

// Include parser if exists, otherwise define basic parser function
if (file_exists('whois.parser.php')) {
    require_once('whois.parser.php');
}

if (!function_exists('easy_parser')) {
    /**
     * Basic parser function for whois data
     *
     * @param array $rawdata Raw whois data lines
     * @param array $items Field mappings
     * @param string $dateFormat Date format (unused in basic version)
     * @return array Parsed data
     */
    function easy_parser($rawdata, $items, $dateFormat = 'Y-m-d')
    {
        $result = [];

        foreach ($items as $key => $pattern) {
            $result[$key] = null;

            foreach ($rawdata as $line) {
                if (strpos($line, $pattern) !== false) {
                    $value = trim(str_replace($pattern, '', $line));
                    $result[$key] = $value;
                    break;
                }
            }
        }

        return $result;
    }
}

class tr_handler
{
    /**
     * Deep whois property
     * @var mixed
     */
    public $deep_whois;

    /**
     * Whois server for Turkish domains
     * @var string
     */
    private $whoisServer = 'whois.trabis.gov.tr';

    /**
     * Parse whois raw data
     *
     * @param array $data_str Array containing rawdata
     * @param string $query Domain name being queried
     * @return array Parsed whois information
     */
    public function parse($data_str, $query)
    {
        // Extract all necessary information
        $domainName = $this->extractField($data_str['rawdata'], '** Domain Name:');
        $createdDate = $this->extractDate($data_str['rawdata'], 'Created on..............:');
        $expiresDate = $this->extractDate($data_str['rawdata'], 'Expires on..............:');
        $changedDate = $this->extractDate($data_str['rawdata'], 'Last Update Time:');
        $nameServers = $this->extractNameServers($data_str['rawdata']);
        $organizationName = $this->extractOrganizationName($data_str['rawdata']);
        $registrarName = $this->normalizeRegistrarName($organizationName);

        // Build structured response matching .com format
        $response = [
            'regrinfo' => [
                'domain' => [
                    'name'    => $domainName ?: $query,
                    'changed' => $changedDate,
                    'created' => $createdDate,
                    'nserver' => $nameServers,
                ],
                'registered' => 'yes',
            ],
            'regyinfo' => [
                'registrar' => $registrarName,
                'type'      => 'domain',
            ],
            'rawdata' => $data_str['rawdata'],
        ];

        // Add expires date if available
        if ($expiresDate) {
            $response['regrinfo']['domain']['expires'] = $expiresDate;
        }

        return $response;
    }

    /**
     * Extract a simple field from raw data
     *
     * @param array $rawdata Array of raw whois lines
     * @param string $pattern Pattern to search for
     * @return string|null Field value or null
     */
    private function extractField($rawdata, $pattern)
    {
        foreach ($rawdata as $line) {
            if (strpos($line, $pattern) !== false) {
                return trim(str_replace($pattern, '', $line));
            }
        }
        return null;
    }

    /**
     * Extract date from raw data and format it
     *
     * @param array $rawdata Array of raw whois lines
     * @param string $pattern Pattern to search for
     * @return string|null Formatted date (d-m-Y) or null
     */
    private function extractDate($rawdata, $pattern)
    {
        foreach ($rawdata as $line) {
            if (strpos($line, $pattern) !== false) {
                // Extract date string
                $dateStr = trim(str_replace($pattern, '', $line));

                // Remove trailing dot
                $dateStr = rtrim($dateStr, '.');

                // Try different date formats

                // Format 1: 2019-Feb-11 (Year-Month-Day with month name)
                if (preg_match('/^(\d{4})-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d{1,2})$/i', $dateStr, $matches)) {
                    $year = $matches[1];
                    $monthMap = [
                        'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4,
                        'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8,
                        'sep' => 9, 'oct' => 10, 'nov' => 11, 'dec' => 12
                    ];
                    $month = $monthMap[strtolower($matches[2])];
                    $day = str_pad($matches[3], 2, '0', STR_PAD_LEFT);
                    return sprintf('%s-%02d-%s', $day, $month, $year);
                }

                // Format 2: ISO 8601 with timezone (2025-11-13T02:19:28+03:00)
                if (strpos($dateStr, 'T') !== false) {
                    $date = DateTime::createFromFormat('Y-m-d\TH:i:sP', $dateStr);
                    if (!$date) {
                        $date = DateTime::createFromFormat('Y-m-d\TH:i:s', $dateStr);
                    }
                    if ($date) {
                        return $date->format('d-m-Y');
                    }
                }

                // Format 3: Y-m-d (2019-02-11)
                $cleanDate = preg_replace('/[^0-9-]/', '', $dateStr);
                if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $cleanDate)) {
                    $date = DateTime::createFromFormat('Y-m-d', $cleanDate);
                    if ($date) {
                        return $date->format('d-m-Y');
                    }
                }
            }
        }

        return null;
    }

    /**
     * Extract name servers from raw data
     *
     * @param array $rawdata Array of raw whois lines
     * @return array Name servers with their IPs
     */
    private function extractNameServers($rawdata)
    {
        $nameservers = [];
        $inNsSection = false;

        foreach ($rawdata as $line) {
            $line = trim($line);

            // Start of name server section
            if (strpos($line, '** Domain Servers:') !== false) {
                $inNsSection = true;
                continue;
            }

            // End of name server section (empty line or new section starting with **)
            if ($inNsSection && ($line === '' || strpos($line, '**') === 0)) {
                break;
            }

            // Extract name server entries
            if ($inNsSection && $line !== '') {
                // Format: ns1.example.com [1.2.3.4]
                // or:     ns1.example.com 1.2.3.4
                if (preg_match('/^([^\s\[]+)\s*(?:\[([^\]]+)\]|(\S+))?/', $line, $matches)) {
                    $ns = strtolower(trim($matches[1]));
                    $ip = isset($matches[2]) && $matches[2] ? trim($matches[2]) : (isset($matches[3]) ? trim($matches[3]) : '');

                    if ($ns) {
                        $nameservers[$ns] = $ip;
                    }
                }
            }
        }

        return $nameservers;
    }

    /**
     * Extract organization name from raw data
     *
     * @param array $rawdata Array of raw whois lines
     * @return string Organization name or empty string
     */
    private function extractOrganizationName($rawdata)
    {
        foreach ($rawdata as $line) {
            // Look for "Organization Name:" field
            if (stripos($line, 'Organization Name') !== false) {
                $parts = explode(':', $line, 2);
                if (isset($parts[1])) {
                    return trim($parts[1]);
                }
            }
        }

        return '';
    }

    /**
     * Normalize registrar name (handle special cases)
     *
     * @param string $organizationName Original organization name
     * @return string Normalized registrar name
     */
    private function normalizeRegistrarName($organizationName)
    {
        // Special case mapping for known registrars
        $specialCases = [
            'ATAK DOMAİN BİLGİ TEKNOLOJİLERİ ANONİM ŞİRKETİ' => 'SERVER SİSTEMLERİ BİLİŞİM SAN. TİC. LTD. ŞTİ.',
            'ATAK DOMAIN BILGI TEKNOLOJILERI ANONIM SIRKETI'  => 'SERVER SİSTEMLERİ BİLİŞİM SAN. TİC. LTD. ŞTİ.',
        ];

        // Check if organization name matches any special case (case-insensitive)
        foreach ($specialCases as $original => $replacement) {
            if (strcasecmp($organizationName, $original) === 0) {
                return $replacement;
            }
        }

        return $organizationName;
    }
}
