<?php

namespace app\command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;


use AcmePhp\Core\Http\Base64SafeEncoder;
use AcmePhp\Core\Http\SecureHttpClientFactory;
use AcmePhp\Core\Http\ServerErrorHandler;
use AcmePhp\Ssl\KeyPair;
use AcmePhp\Ssl\PrivateKey;
use AcmePhp\Ssl\PublicKey;
use AcmePhp\Ssl\Parser\KeyParser;
use AcmePhp\Ssl\Signer\DataSigner;
use GuzzleHttp\Client as GuzzleHttpClient;
use AcmePhp\Ssl\DistinguishedName;
use AcmePhp\Ssl\CertificateRequest;
use AcmePhp\Ssl\Generator\KeyPairGenerator;
use AcmePhp\Core\Challenge\Dns\DnsDataExtractor;

use AcmePhp\Core\AcmeClient;

class Acme extends Command
{
    protected static $defaultName = 'acme';
    protected static $defaultDescription = 'acme';

    /**
     * @return void
     */
    protected function configure()
    {
        $this->addArgument('name', InputArgument::OPTIONAL, 'Name description');
    }

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return int
     */
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $EMAIL='youremail@yourdomain.com';
        $DOMAIN='yourdomain.com';
        #$CA='https://acme-v02.api.letsencrypt.org/directory';
        $CA='https://acme-staging-v02.api.letsencrypt.org/directory';
        $secureHttpClientFactory = new SecureHttpClientFactory(
            new GuzzleHttpClient(),
            new Base64SafeEncoder(),
            new KeyParser(),
            new DataSigner(),
            new ServerErrorHandler()
        );
                
        $publicKeyPath = base_path().'/keys/account.pub.pem';
        $privateKeyPath = base_path().'/keys/account.pem';
        
        if (!file_exists($privateKeyPath)) {
            $keyPairGenerator = new KeyPairGenerator();
            $keyPair = $keyPairGenerator->generateKeyPair();
        
            file_put_contents($publicKeyPath, $keyPair->getPublicKey()->getPEM());
            file_put_contents($privateKeyPath, $keyPair->getPrivateKey()->getPEM());
        } else {
            $publicKey = new PublicKey(file_get_contents($publicKeyPath));
            $privateKey = new PrivateKey(file_get_contents($privateKeyPath));
        
            $keyPair = new KeyPair($publicKey, $privateKey);
        }
        $secureHttpClient = $secureHttpClientFactory->createSecureHttpClient($keyPair);

        #$acmeClient = new AcmeClient($secureHttpClient, 'https://acme-v02.api.letsencrypt.org/directory');
        $acmeClient = new AcmeClient($secureHttpClient, $CA);
        
        $acmeClient->registerAccount($EMAIL,null);
        
        $authorizationChallenges = $acmeClient->requestAuthorization($DOMAIN);
        
        foreach($authorizationChallenges as $id=>$cha){
        
                $cha->id=$id;
                $dde=new DnsDataExtractor;
                $cha->value=$dde->getRecordValue($cha);
                print_r($cha);
        }
        #print_r($authorizationChallenges);
       

        #print_r($dde->getRecordValue($authorizationChallenges[1]));

        #$output->writeln($authorizationChallenges);

        $helper = $this->getHelper('question');
        $question = new ChoiceQuestion(
            '选择对应的ID',
            array('0', '1', '2'),
            0
        ); 
        $way = $helper->ask($input, $output, $question);

        $acmeClient->challengeAuthorization($authorizationChallenges[$way]);

        $dn = new DistinguishedName($DOMAIN);

        $keyPairGenerator = new KeyPairGenerator();

        // Make a new key pair. We'll keep the private key as our cert key
        $domainKeyPair = $keyPairGenerator->generateKeyPair();

        // This is the private key
        var_dump($domainKeyPair->getPrivateKey()->getPem());

        // Generate CSR
        $csr = new CertificateRequest($dn, $domainKeyPair);

        $certificateResponse = $acmeClient->requestCertificate($DOMAIN, $csr);

        // This is the certificate (public key)
        var_dump($certificateResponse->getCertificate()->getPem());

        // For Let's Encrypt, you will need the intermediate too
        var_dump($certificateResponse->getCertificate()->getIssuerCertificate()->getPEM());

        return self::SUCCESS;
    }

}
