<commit_before><?php
namespace Junior;
use Junior\Clientside\Request,
    Junior\Clientside\Response,
    Junior\Clientside\Exception;

foreach(array('Request', 'Response', 'Exception') as $file) {
    require_once('Junior'. DIRECTORY_SEPARATOR . 'Clientside' . DIRECTORY_SEPARATOR . $file . '.php');
}

class Client {

    // create new client connection
    public function __construct($uri)
    {
        $this->uri = $uri;
    }

    // shortcut to call a single, non-notification request
    public function __call($method, $params)
    {
        $req = new Request($method, $params);
        return $this->sendRequest($req);
    }

    // send a single request object
    public function sendRequest($req)
    {
        $response = $this->send($req->getJSON());

        if ($response->id != $req->id) {
            throw new Exception("Mismatched request id");
        }

        if($response->error_code) {
            throw new Exception("{$response->error_code} {$response->error_message}");
        }

        return $response->result;
    }

    // send a single notify request object
    public function sendNotify($req)
    {
        if (property_exists($req, 'id')) {
            throw new Exception("Notify requests must not have ID set");
        }

        $this->send($req->getJSON(), true);
        return true;
    }

    // send an array of request objects as a batch
    public function sendBatch($reqs)
    {
        $arr = array();
        $ids = array();
        $all_notify = true;
        foreach ($reqs as $req) {
            if ($req->id) {
                $all_notify = false;
                $ids[] = $req->id;
            }
            $arr[] = $req->getArray();
        }
        $response = $this->send(json_encode($arr), $all_notify);

        // no response if batch is all notifications
        if ($all_notify) {
            return true;
        }

        // check for missing ids and return responses in order of requests
        $ordered_response = array();
        foreach ($ids as $id) {
            if (array_key_exists($id, $response)) {
                $ordered_response[] = $response[$id];
                unset($response[$id]);
            } else {
                throw new Exception("Missing id in response");
            }
        }

        // check for extra ids in response
        if (count($response) > 0) {
            throw new Exception("Extra id(s) in response");
        }

        return $ordered_response;
    }

    // send raw json to the server
    public function send($json, $notify = false)
    {
        // prepare data to be sent
        $opts = array(
            'http' => array(
                'method'  => 'POST',
                'header'  => 'Content-Type: application/json\r\n',
                'content' => $json));
        $context = stream_context_create($opts);

        // try to physically send data to destination 
        try {
            $response = file_get_contents($this->uri, false, $context);
        } catch (\Exception $e) {
            $message = "Unable to connect to {$this->uri}";
            $message .= PHP_EOL . $e->getMessage();
            throw new Exception($message);
        }

        // handle communication errors
        if ($response === false) {
            throw new Exception("Unable to connect to {$this->uri}");
        }

        // notify has no response
        if ($notify) {
            return true;
        }

        // try to decode json
        $response = json_decode($response);
        if ($response === null) {
            throw new Exception("Unable to decode JSON response");
        }

        // handle response, create response object and return it
        return $this->handleResponse($response);
    }

    // handle the response and return a result or an error
    public function handleResponse($response)
    {
        // recursion for batch
        if (is_array($response)) {
            $response_arr = array();
            foreach ($response as $res) {
                $response_arr[$res->id] = $this->handleResponse($res);
            }
            return $response_arr;
        }

        // return error response
        if (property_exists($response, 'error')) {
            return new Response(null, $response->id, $response->error->code, $response->error->message);
        }

        // return successful response
        return new Response($response->result, $response->id);
    }

}

?>
?><commit_msg>remove extra closing php tag and include raw response in error when json response was not decoded<commit_after><?php
namespace Junior;
use Junior\Clientside\Request,
    Junior\Clientside\Response,
    Junior\Clientside\Exception;

foreach(array('Request', 'Response', 'Exception') as $file) {
    require_once('Junior'. DIRECTORY_SEPARATOR . 'Clientside' . DIRECTORY_SEPARATOR . $file . '.php');
}

class Client {

    // create new client connection
    public function __construct($uri)
    {
        $this->uri = $uri;
    }

    // shortcut to call a single, non-notification request
    public function __call($method, $params)
    {
        $req = new Request($method, $params);
        return $this->sendRequest($req);
    }

    // send a single request object
    public function sendRequest($req)
    {
        $response = $this->send($req->getJSON());

        if ($response->id != $req->id) {
            throw new Exception("Mismatched request id");
        }

        if($response->error_code) {
            throw new Exception("{$response->error_code} {$response->error_message}");
        }

        return $response->result;
    }

    // send a single notify request object
    public function sendNotify($req)
    {
        if (property_exists($req, 'id')) {
            throw new Exception("Notify requests must not have ID set");
        }

        $this->send($req->getJSON(), true);
        return true;
    }

    // send an array of request objects as a batch
    public function sendBatch($reqs)
    {
        $arr = array();
        $ids = array();
        $all_notify = true;
        foreach ($reqs as $req) {
            if ($req->id) {
                $all_notify = false;
                $ids[] = $req->id;
            }
            $arr[] = $req->getArray();
        }
        $response = $this->send(json_encode($arr), $all_notify);

        // no response if batch is all notifications
        if ($all_notify) {
            return true;
        }

        // check for missing ids and return responses in order of requests
        $ordered_response = array();
        foreach ($ids as $id) {
            if (array_key_exists($id, $response)) {
                $ordered_response[] = $response[$id];
                unset($response[$id]);
            } else {
                throw new Exception("Missing id in response");
            }
        }

        // check for extra ids in response
        if (count($response) > 0) {
            throw new Exception("Extra id(s) in response");
        }

        return $ordered_response;
    }

    // send raw json to the server
    public function send($json, $notify = false)
    {
        // prepare data to be sent
        $opts = array(
            'http' => array(
                'method'  => 'POST',
                'header'  => 'Content-Type: application/json\r\n',
                'content' => $json));
        $context = stream_context_create($opts);

        // try to physically send data to destination 
        try {
            $response = file_get_contents($this->uri, false, $context);
        } catch (\Exception $e) {
            $message = "Unable to connect to {$this->uri}";
            $message .= PHP_EOL . $e->getMessage();
            throw new Exception($message);
        }

        // handle communication errors
        if ($response === false) {
            throw new Exception("Unable to connect to {$this->uri}");
        }

        // notify has no response
        if ($notify) {
            return true;
        }

        // try to decode json
        $json_response = json_decode($response);
        if ($json_response === null) {
            throw new Exception("Unable to decode JSON response from: {$response}");
        }

        // handle response, create response object and return it
        return $this->handleResponse($json_response);
    }

    // handle the response and return a result or an error
    public function handleResponse($response)
    {
        // recursion for batch
        if (is_array($response)) {
            $response_arr = array();
            foreach ($response as $res) {
                $response_arr[$res->id] = $this->handleResponse($res);
            }
            return $response_arr;
        }

        // return error response
        if (property_exists($response, 'error')) {
            return new Response(null, $response->id, $response->error->code, $response->error->message);
        }

        // return successful response
        return new Response($response->result, $response->id);
    }

}

?>
{'fraction_non_alphanumeric': 0.1267449590073122, 'fraction_numerical': 0.00022158209616662973, 'mean_word_length': 1.8512318382817434, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 76, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1164515', 'n_tokens_mistral': 2412, 'n_tokens_neox': 2349, 'n_words': 692}