<?php

namespace Darksparrow\DeegraphInteractions\Core;

use Darksparrow\DeegraphInteractions\DataStructures\QueryResponseWrapper;
use Darksparrow\DeegraphInteractions\DataStructures\ServerInfo;
use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\InsertQuery;
use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\PutQuery;
use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\SelectQuery;

class DeegraphServer
{
    private string $Token;
    private string $Actor;


    private string $ServerDomain;
    private int $Port;
    private bool $AllowSelfSignedCerts;

    public function __construct(
        string $token,
        string $actor,
        string $server = "localhost",
        int $port = 8088,
        bool $allowSelfSignedCerts = false)
    {
        $this->Token = $token;
        $this->Actor = $actor;

        $this->ServerDomain = $server;
        $this->Port = $port;
        $this->AllowSelfSignedCerts = $allowSelfSignedCerts;
    }

    /**
     * Runs an API request against the Deegraph Server, and returns back information about the Deegraph Server.
     * @return ServerInfo
     */
    public function ServerInfo(): ServerInfo
    {
        $response = $this->RunRawRequest(endpoint: "/api/v1/@server_info");
        return ServerInfo::FromAPIResponse(response: $response);
    }

    private function RunRawRequest(string $endpoint, string $method = "GET", string $body = null): string
    {
        $ch = curl_init("https://{$this->ServerDomain}:{$this->Port}{$endpoint}");
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            "Authorization: Bearer {$this->Token}",
            "X-Auxilium-Actor: {$this->Actor}",
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        if ($method == "POST") {
            curl_setopt($ch, CURLOPT_POST, 1);
        }
        if($this->AllowSelfSignedCerts)
        {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }

        if ($method == "POST" || $method == "PUT") {
            if ($body != null) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
            }
        }

        $result = curl_exec($ch);

        if(curl_error($ch) == "SSL certificate problem: unable to get local issuer certificate")
        {
            throw new \Exception();
            die();
        }

        curl_close($ch);

        return $result;
    }

    /**
     * @param InsertQuery|PutQuery|SelectQuery $query Takes in a Query Builder object.
     * @return QueryResponseWrapper
     */
    public function RunQuery(InsertQuery|PutQuery|SelectQuery $query): QueryResponseWrapper
    {
        $response = $this->RunRawRequest(
            endpoint: "/api/v1/@query",
            method: "POST",
            body: $query
        );
        return QueryResponseWrapper::FromAPIResponse($response);
    }
}