<?php
class SMTP_Probe {
    public $options;

    function __construct($options = []) {
        $hostname = gethostname();
        $server_ip = gethostbyname($hostname);
        $server_domain = php_uname('n');
        $fallback_helo = !empty($server_domain) ? $server_domain : $hostname;

        // MAIL_FROM آمن أكثر
        $default_from = 'probe@' . ($_SERVER['HTTP_HOST'] ?? $hostname);

        $this->options = array_merge([
            'HELLO_FQDN' => $fallback_helo,
            'MAIL_FROM' => $default_from,
            'TIMEOUT' => 5
        ], $options);
    }

    function check_one($email) {
        $domain = strtolower(substr(strrchr($email, "@"), 1));
        if (!$domain) return $this->format($email, 'invalid', '', '', 'Invalid email format');

        $mxs = $this->get_mx_hosts($domain);
        if (empty($mxs)) return $this->format($email, 'unknown', '', '', 'No MX records found');

        foreach ($mxs as $mx) {
            $res = $this->check_with_mx($mx, $email);
            if ($res['status'] === 'deliverable') return $res;
            if ($res['status'] === 'undeliverable') return $res;
        }
        return $this->format($email, 'unknown', $mxs[0], '', 'All attempts returned unknown');
    }

    private function check_with_mx($mx, $email) {
        $sock = @fsockopen($mx, 25, $errno, $errstr, $this->options['TIMEOUT']);
        if (!$sock) return $this->format($email, 'unknown', $mx, '', "Connection failed: $errstr");

        stream_set_timeout($sock, $this->options['TIMEOUT']);
        $this->read($sock);
        $this->send($sock, "HELO " . $this->options['HELLO_FQDN']);
        $this->read($sock);
        $this->send($sock, "MAIL FROM:<" . $this->options['MAIL_FROM'] . ">");
        $this->read($sock);
        $this->send($sock, "RCPT TO:<$email>");
        $rcpt = $this->read($sock);
        $this->send($sock, "QUIT");
        fclose($sock);

        $code = (int)substr($rcpt, 0, 3);
        if ($code >= 200 && $code < 300) return $this->format($email, 'deliverable', $mx, $code, $rcpt);
        elseif ($code >= 500 && $code < 600) return $this->format($email, 'undeliverable', $mx, $code, $rcpt);
        else return $this->format($email, 'unknown', $mx, $code, $rcpt);
    }

    private function send($sock, $cmd) {
        fwrite($sock, $cmd . "\r\n");
    }

    private function read($sock) {
        $out = '';
        while ($line = fgets($sock, 515)) {
            $out .= $line;
            if (preg_match('/^\d{3} /', $line)) break;
        }
        return trim($out);
    }

    private function get_mx_hosts($domain) {
        if (function_exists('getmxrr') && getmxrr($domain, $hosts)) return $hosts;

        $recs = dns_get_record($domain, DNS_MX);
        if ($recs) return array_column($recs, 'target');

        $ip = gethostbyname($domain);
        return ($ip && $ip !== $domain) ? [$ip] : [];
    }

    private function format($email, $status, $mx, $code, $msg) {
        return [
            'email' => $email,
            'status' => $status,
            'mx' => $mx,
            'code' => $code,
            'msg' => $msg
        ];
    }
}

// API Endpoint
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    header('Content-Type: application/json; charset=utf-8');
    $input = json_decode(file_get_contents("php://input"), true);
    $emails = explode("\n", trim($input['emails'] ?? ''));
    $checked = [];
    $probe = new SMTP_Probe();
    foreach ($emails as $email) {
        $email = trim($email);
        if (!$email) continue;
        $checked[] = $probe->check_one($email);
    }
    echo json_encode($checked, JSON_UNESCAPED_UNICODE);
}
?>
