<?php
/**
 * Created by PhpStorm.
 * User: eater
 * Date: 4/4/16
 * Time: 9:23 PM
 */

namespace Eater\Glim\Handler\Panel\Certificates\_New;


use Eater\Glim\Handler\Session;
use Eater\Glim\Model\Certificate;
use Eater\Glim\Model\CertificateQuery;
use Eater\Glim\Service\CA;
use Slim\Http\Response;

class Action extends Session
{
    protected $shouldHaveUser = true;

    /**
     * @return Response
     */
    public function handle()
    {
        $user = $this->getUser();
        $core = $this->getCore();
        /** @var CA $ca */
        $ca = $this->get('ca');

        $name = $this->post('name');
        $csr = $this->post('csr');

        $amount = CertificateQuery::create()
            ->filterByName($name)
            ->filterByUser($user)
            ->count();
        if ($amount > 0) {
            return $this->json([
                "error" => "You already have an Certificate with the name '$name'",
                "success" => false
            ]);
        }

        try {
            $commonName = $ca->getCommonNameFromCsr($csr);
        }catch (\Exception $e) {
            return $this->json([
               "error" => $e->getMessage(),
               "success" => false
            ]);
        }

        $designatedCommonName = $name . '.' . $user->getUsername();

        if ($commonName !== $name . '.' .  $user->getUsername()) {
            return $this->json([
                "error" => "CommonName of CSR isn't '$designatedCommonName'",
                "success" => false
            ]);
        }

        $crt = $ca->signClientCsr($csr);

        $details = openssl_x509_parse($crt);

        $certificate = new Certificate();
        $certificate->setName($name);
        $certificate->setCertificate($crt);
        $certificate->setExpiresOn(new \DateTime('@' . $details['validTo_time_t']));

        if (!empty($this->post('key'))) {
            $certificate->setPrivateKey($this->post('key'));
        }

        $certificate->setSerial($details['serialNumber']);

        $user->addCertificate($certificate);
        $user->save();

        return $this->json([
            "success" => true,
            "zip" => [
                "ca.crt" => file_get_contents($core->getBaseDir() . '/storage/ca/ca.crt'),
                $designatedCommonName . '.crt' => $crt
            ]
        ]);
    }
}