<?php

namespace Eater\Glim\Handler\Server;

use Eater\Glim\Handler\Main;
use Eater\Glim\Model\Server;
use Eater\Glim\Model\ServerQuery;
use Eater\Glim\Service\CA;

class Register extends Main
{
    public function handle()
    {

        /** @var CA $ca */
        $ca = $this->get('ca');

        $publicKey = $this->post('publicKey');
        $hexSignature = $this->post('signature');
        $fingerprint = $ca->getFingerprintFromPublicKey($publicKey);

        if (empty($publicKey)) {
            return $this->bash(false, "no PublicKey was provided\n" . var_export($_POST, true) . "\n" . var_export($_FILES, true));
        }

        if (empty($hexSignature)) {
            return $this->bash(false, "no signature was provided\n" . var_export($_POST));
        }

        $serverQuery = ServerQuery::create();
        $server = $serverQuery->findOneByFingerprint($fingerprint);

        $signature = hex2bin($hexSignature);

        if ($server !== null) {
            return $this->bash(false, "Server with this fingerprint already exists, if you want to change IP please use /server/update-ip or regenerate your public key");
        }

        try {
            $result = $ca->verify($fingerprint, $signature, $publicKey);
        } catch (\Exception $e) {
            return $this->bash(false, "Verifying went into error: " . $e->getMessage());
        }

        if ($result) {
            return $this->bash(false, "Signature is erroneous\nSignature: {$hexSignature}\nFingerprint: {$fingerprint}\nOpenSSL: " . openssl_error_string());
        }

        $ip = $_SERVER['REMOTE_ADDR'];
        $originalIp = $ip;
        $fqdn = gethostbyaddr($ip);
        $ipOfFqdn = gethostbyname($fqdn);

        if ($ip === $ipOfFqdn) {
            $ip = $fqdn;
        }

        $server = new Server();
        $server->setFingerprint($fingerprint);
        $server->setFqdn($ip);
        $server->setExternalIp($originalIp);
        $server->setPublicKey($publicKey);
        $server->save();

        return $this->bash(true, "Good job, skeleton");
    }

    public function bash($result, $message)
    {
        return $this->getResponse()->write(($result ? 0 : 1) . "\n" . $message);
    }
}