<?php namespace Client\Request;

abstract class Base implements RequestInterface {

    protected $loaded = false;
    protected $scope;

    use \Lib\Curl {
        get as private mget;
        post as protected mpost;
        delete as protected mdelete;
    }

    public function __construct(string $api_url, string $api_token) {
        $this->url = $api_url;
        $this->token = $api_token;
    }

    public function load(bool $force = false) {
        $this->set_scope("get");

        if ($this->loaded && !$force)
            return $this;

        $jenc =  $this->mget($this->scope);

        $this->json_set_property($this->json_decode($jenc));
        $this->loaded = true;

        return $this;
    }

    protected function method_get(array $params = array()) {
        return $this->mget($this->scope, $params);
    }

    protected function method_post(array $params = array()) {
        return $this->mpost($this->scope, $params);
    }

    protected function method_delete() {
        return $this->mdelete($this->scope);
    }

    public function get(string $s) {
        $this->set_scope("get");
    }

    public function create(...$args) {
        $this->set_scope("create");
        $ret = $this->method_post(...$args);

        $this->json_set_property($this->json_decode($ret));
        $this->loaded = true;

        return true;
    }

    public function patch() {
        $this->set_scope("patch");
    }

    public function delete() {
        $this->set_scope("delete");
        return $this->method_delete();
    }

    protected function json_decode(string $jenc) {
        $obj = json_decode($jenc);

        $this->json_error();

        return $obj;
    }

    protected function json_encode(iterable $jdec) {
        $jenc = json_encode($jdec);

        $this->json_error();

        return $jenc;
    }

    protected function json_error() {
        if (($err = json_last_error()) != JSON_ERROR_NONE)
            throw new RequestErrorException(json_last_error_msg(), $err);
    }

    abstract protected function json_set_property($obj);
    abstract protected function set_scope(string $method);

    public function __destruct() {}
}

?>