<?php

declare(strict_types=1);

/**
 * SPDX-FileCopyrightText: 2024 Sebastian Krupinski <krupinski01@gmail.com>
 * SPDX-License-Identifier: AGPL-3.0-only
 */

namespace JmapClient\Requests;

class Request implements \JsonSerializable
{
    public const REQUEST_OPERATION = 0;
    public const REQUEST_COMMAND = 1;
    public const REQUEST_IDENTIFIER = 2;

    public const DATE_FORMAT_LOCAL = 'Y-m-d\TH:i:s';
    public const DATE_FORMAT_UTC = 'Y-m-d\TH:i:s\Z';

    protected string $_space;
    protected string $_class;
    protected string $_method;
    protected string $_account;
    protected string $_identifier;
    protected string $_operation;
    protected array $_command;
    protected array $_request = ['/', [], ''];

    public function __construct(?string $account = null, ?string $identifier = null, ?string $space = null, ?string $class = null, ?string $method = null)
    {
        if ($account !== null) {
            $this->_account = $account;
        }
        if ($identifier !== null) {
            $this->_identifier = $identifier;
        }
        if ($space !== null) {
            $this->_space = $space;
        }
        if ($class !== null) {
            $this->_class = $class;
        }
        if ($method !== null) {
            $this->_method = $method;
        }
        if ($this->_account === null) {
            $this->_account = 'default';
        }
        if (!isset($this->_identifier)) {
            $this->_identifier = uniqid();
        }
        if (!isset($this->_space)) {
            $this->_space = 'core';
        }
        if (!isset($this->_class)) {
            $this->_class = 'Core';
        }
        if (!isset($this->_method)) {
            $this->_method = 'echo';
        }
        $this->_request[self::REQUEST_OPERATION] = $this->_class . '/' . $this->_method;
        $this->_request[self::REQUEST_COMMAND] = ['accountId' => $this->_account];
        $this->_request[self::REQUEST_IDENTIFIER] = $this->_identifier;

        $this->_command = & $this->_request[self::REQUEST_COMMAND];
    }

    public function jsonSerialize(): array
    {
        return $this->_request;
    }

    public function jsonEncode(int $flags = 0): string
    {
        return json_encode($this->_request, JSON_UNESCAPED_SLASHES | $flags);
    }

    public function getIdentifier(): string
    {
        return $this->_identifier;
    }

    public function setIdentifier(string $identifier): void
    {
        $this->_identifier = $identifier;
        $this->_request[self::REQUEST_IDENTIFIER] = $identifier;
    }

    public function getAccount(): string
    {
        return $this->_account;
    }

    public function setAccount(string $account): void
    {
        $this->_account = $account;
        $this->_command['accountId'] = $account;
    }

    public function getNamespace(): string
    {
        return $this->_space;
    }

    public function setNamespace(string $space): void
    {
        $this->_space = $space;
    }

    public function getClass(): string
    {
        return $this->_class;
    }

    public function setClass(string $class): void
    {
        $this->_class = $class;
        $this->_request[self::REQUEST_OPERATION] = $class . '/' . $this->_method;
    }

    public function getMethod(): string
    {
        return $this->_method;
    }

    public function setMethod(string $method): void
    {
        $this->_method = $method;
        $this->_request[self::REQUEST_OPERATION] = $this->_class . '/' . $method;
    }
}
