<?php

namespace App\Helpers;

/**
 *
 *
 *
 *
 */
class NginxVhostHelper
{
    // path for available files
    const SITES_AVAILABLE = '/etc/nginx/sites-available';

    // path for enabled files
    const SITES_ENABLED = '/etc/nginx/sites-enabled';

    // regex to get files for
    const REGEX_SSL_CERTIFICATE = '/\bssl_certificate\s+\K\S+/';
    const REGEX_SSL_CERTIFICATE_KEY = '/\bssl_certificate_key\s+\K\S+/';

    // ignore files
    const IGNORE_FILES = [
        '.', '..'
    ];

    /**
     *
     *
     *
     *  @return array
     *
     */
    private function getSitesAvailable()
    {
        return scandir(self::SITES_AVAILABLE);
    }

    /**
     *
     *
     *
     *  @return array
     *
     */
    private function getSitesEnabled()
    {
        return scandir(self::SITES_ENABLED);
    }

    /**
     *  find path for certificates in .conf-files
     *
     *
     *  ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
     *  ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;
     *
     */
    private function getCertificate($path)
    {
        $result = [
            'ssl' => false,
            'ssl_certificate_exists' => false,
            'ssl_certificate_expired_at' => false
        ];

        // getting .conf-file
        $content = file_get_contents($path);

        // check for path of sites
        preg_match(self::REGEX_SSL_CERTIFICATE, $content, $matches);
        preg_match(self::REGEX_SSL_CERTIFICATE_KEY, $content, $matches);

        // check for ssl certificates
        if (count($matches) >= 2) {
            $result['ssl'] = true;

            if (file_exists($matches[0]) && file_exists($matches[1])) {
                $result['ssl_certificate_exists'] = true;
            }

            exec('openssl x509 -noout -dates -in '.$path, $openssl);

            if (isset($openssl[1])) {
                $openssl = str_replace('notAfter=', '', $openssl[1]);

            }
        }

        return $result;
    }

    private function getVhost($filename, $enabled)
    {
        // getting full path
        $path = self::SITES_AVAILABLE.'/'.$filename;

        // getting certificates from a configuration
        $certificate = $this->getCertificate($path);

        $result = array_merge([
            'domain' => str_replace('.conf', '', $filename),
            'path' => $path,
            'file' => $filename,
            'enabled' => in_array($filename, $enabled),
        ], $certificate);

        return $result;
    }

    public function findOneByFilename($filename)
    {
        // getting enabled
        $enabled = $this->getSitesEnabled();
        return $this->getVhost($filename, $enabled);
    }

    /**
     * getting vhosts
     *
     */
    public function find()
    {
        $results = [];

        // getting available
        $available = $this->getSitesAvailable();

        // getting enabled
        $enabled = $this->getSitesEnabled();

        foreach($available as $filename)
        {
            if (!in_array($filename, self::IGNORE_FILES)) {
                $results[] = $this->getVhost($filename, $enabled);
            }
        }

        return $results;
    }
}