<?php

namespace App\Checklist;

use App\Contracts\GoLiveChecklist;

class CheckPrimaryDomainSsl implements GoLiveChecklist
{
    /**
     * Name of the check
     *
     * @return string
     */
    public function name(): string
    {
        return __('go-live.primary_domain_ssl');
    }

    /**
     * Has the check passed
     *
     * @return bool|null
     */
    public function passes(): ?bool
    {
        return tenant()->domains()
            ->where('primary', 1)
            ->exists();
    }

    /**
     * Url to perform check
     *
     * @return string
     */
    public function urlToCheck(): string
    {
        return route('tenant.checklists.ssl', tenant()->domains()->where('primary', 1)->first()->id ?? 0);
    }

    /**
     * Check if domain has SSL
     *
     * @param $domain
     * @return bool
     */
    public function hasSsl($domain)
    {
        $hasSsl = false;
        $sslUrl = 'ssl://' . $domain . ':443';
        $stream = @stream_context_create([
            'ssl' => ['capture_peer_cert' => true]
        ]);
        $socket = @stream_socket_client($sslUrl, $errno, $errStr, 30, STREAM_CLIENT_CONNECT, $stream);

        if (empty($socket)) {
            return false;
        }

        $context = stream_context_get_params($socket);
        $certificateResource = $context['options']['ssl']['peer_certificate'];
        $certificate = openssl_x509_parse($certificateResource);

        // Expected name has format "/CN=*.yourdomain.com"
        $parts = explode('=', $certificate['name']);

        // We want to correctly confirm the certificate even
        // for subdomains like "www.yourdomain.com"
        if (count($parts) == 2) {
            $certDomain = trim($parts[1], '*. ');
            $checkDomain = substr($domain, -strlen($certDomain));
            $hasSsl = ($certDomain == $checkDomain);
        }

        return $hasSsl;
    }
}
