<?php

namespace app\commands;

use app\commands\helpers\Spinner;
use app\commands\helpers\Timer;
use app\components\OneSpaceServiceClient;
use app\models\ED25519;
use app\models\Proto;
use OS\PB\LogMessage;
use OS\PB\Message;
use OS\PB\Packet;
use OS\PB\Packet\PacketTypes;
use Yii;
use yii\console\Controller;

class OzController extends Controller {
    use Timer;
    use Spinner;


    public function actionDemo($i = 1) {
        switch ($i) {
            case 1:
                $this->veryBasicDemo();
                break;
            case 2:
                $this->postDemo();
                break;
            case 3:
                $this->toProtoDemo();
                break;
            default:
                echo "Invalid selection";
        }
        echo "\n\n";
    }


    private function toProtoDemo(): void {
        /** @var OneSpaceServiceClient $client */
        $client = Yii::$app->onespaceServiceClient;

        $url = "http://localhost/v1/api/to-protobuf";
        $response = $client->post($url, [
            'PacketType' => PacketTypes::PacketType_Response_NACK_Corrupt,
            'DestinationSerial' => random_int(1, 199999),
        ], ['Content-Type' => 'application/json'])->send();

        if ($response->isOk) {
            echo "OK - To PB\n";
            $p = new Packet();
            $p->mergeFromString($response->content);

            $url = "http://localhost/v1/api/to-json";
            $response2 = $client->post(
                $url,
                "{$response->content}",
                ['Content-Type' => Proto::CONTENT_TYPE]
            )->send();
            if ($response2->isOk) {
                echo "OK - To JSON\n";
                print_r($response2->data);
            } else {
                echo "NOT OK - To JSON\n";
                print_r($response2->content);
            }
        } else {
            echo "NOT OK - To PB\n";
            print_r($response->content);
        }
    }


    private function postDemo(): void {
        $testSerial = random_int(1, 5000);

        $p = new Packet;
        $p->setSourceSerial($testSerial);
        $p->setPacketType(PacketTypes::PacketType_Data_QoS0);
        $p->setMessages([
            (new Message())->setLog(
                (new LogMessage)->setInfo("The message has been sent successfully")
            ),
            (new Message())->setLog(
                (new LogMessage)->setInfo("So has this one")
            ),
        ]);

        $p->setEncryptedMessages([
            "The Rain in Spain",
        ]);

        $data = $p->serializeToString();


        /** @var OneSpaceServiceClient $client */
        $client = Yii::$app->onespaceServiceClient;

        $url = "http://localhost/v1/demo/demo";
        $response = $client->post(
            $url,
            $data,
            ['Content-Type' => Proto::CONTENT_TYPE]
        )->send();

        if ($response->isOk) {
            print_r("SUCCESS:\n");
            print_r($response->data);
        } else {
            print_r("An Error has occured\n");
            print_r($response->content);
        }
    }


    private function veryBasicDemo(): void {
        $testSerial = random_int(1, 255);

        $p = new Packet;
        $p->setSourceSerial($testSerial);
        $p->setPacketType(PacketTypes::PacketType_Data_QoS0);
        $p->setMessages([
            (new Message())->setLog(
                (new LogMessage)->setInfo("The message has been sent successfully")
            ),
            (new Message())->setLog(
                (new LogMessage)->setInfo("So has this one")
            ),
        ]);

        $data = $p->serializeToString();

        $q = new Packet();
        try {
            $q->mergeFromString($data);
        } catch (\Throwable $th) {
            print_r($th->getMessage());
            exit(1);
        }

        print_r("Source UUID: {$testSerial}\nReceived UUID: {$q->getSourceSerial()}\n\n");
        $messages = $q->getMessages();
        for ($i = 0; $i < $messages->count(); $i++) {
            $message = $messages->offsetGet($i);
            print_r($message->getLog()->getInfo() . "\n");
        }
    }


    public function actionTestEncrypt(): void {
        echo "\n";
        $enc = new ED25519;
        $message = "The rain in Spain stays mainly on the plain.";

        $enc->generateKeyPair();
        $signature = $enc->sign($message, $enc->getSecretKey());
        $verify = $enc->verify($message, $signature, $enc->getPublicKey());

        print_r($signature);
        echo "\n";
        var_dump($verify);

        $encryptedMessage = $enc->encrypt($message, $enc->getPublicKey());
        print_r($encryptedMessage);
        echo "\n";
        $decryptedMessage = $enc->decrypt($encryptedMessage, $enc->getPublicKey());
        print_r($decryptedMessage);
        echo "\n";
        var_dump($message === $decryptedMessage);

        echo "\n\n";
    }
}
