<commit_before><?php
/**
 * MkLiveStatusClient - Client
 *
 * @author <NAME> <<EMAIL>>
 * @license MIT
 */
namespace Kwkm\MkLiveStatusClient;

use \BadFunctionCallException;
use \InvalidArgumentException;
use \RuntimeException;

/**
 * Class Client
 * @package Kwkm\MkLiveStatusClient
 */
class Client
{
    /**
     * 接続方式(unix or tcp)
     * @var string
     */
    protected $socketType = "unix";

    /**
     * ソケットファイル
     * @var string
     */
    protected $socketPath = "/var/run/nagios/rw/live";

    /**
     * TCP接続時のIPアドレス
     * @var string
     */
    protected $socketAddress = "";

    /**
     * TCP接続時のポート
     * @var string
     */
    protected $socketPort = "";

    /**
     * TCP接続時のタイムアウト秒数
     * @var array
     * @link http://php.net/manual/en/function.socket-set-option.php
     */
    protected $socketTimeout = array();

    /**
     * ソケットのリソース
     * @var resource
     */
    protected $socket = null;

    /**
     * コンストラクタ
     *
     * @param array $conf
     * @throw \BadFunctionCallException
     * @throw \InvalidArgumentException
     */
    public function __construct(array $conf)
    {
        if (!function_exists("socket_create")) {
            throw new BadFunctionCallException("The PHP function socket_create is not available.");
        }

        $this->assignProperty($conf);

        $this->validateProperty();

        $this->reset();
    }

    /**
     * 設定をプロパティに割り当て
     *
     * @param array $conf
     */
    private function assignProperty($conf)
    {
        foreach ($conf as $key => $value) {
            if (property_exists($this, $key)) {
                $this->{$key} = $value;
            } else {
                throw new InvalidArgumentException("The option '$key' is not recognised.");
            }
        }
    }

    /**
     * プロパティの値の妥当性を確認
     */
    private function validateProperty()
    {
        switch ($this->socketType) {
            case "unix":
                $this->validatePropetrySocketPath();
                break;
            case "tcp":
                $this->validatePropetrySocketAddress();
                $this->validatePropetrySocketPort();
                break;
            default:
                throw new InvalidArgumentException("Socket Type is invalid. Must be one of 'unix' or 'tcp'.");
        }
    }

    private function validatePropetrySocketPath()
    {
        if (strlen($this->socketPath) === 0) {
            throw new InvalidArgumentException("The option socketPath must be supplied for socketType 'unix'.");
        }
        if (!file_exists($this->socketPath) || !is_readable($this->socketPath) || !is_writable($this->socketPath)) {
            throw new InvalidArgumentException("The supplied socketPath '{$this->socketPath}' is not accessible to this script.");
        }
    }

    private function validatePropetrySocketAddress()
    {
        if (strlen($this->socketAddress) === 0) {
            throw new InvalidArgumentException("The option socketAddress must be supplied for socketType 'tcp'.");
        }
    }

    private function validatePropetrySocketPort()
    {
        if (strlen($this->socketPort) === 0) {
            throw new InvalidArgumentException("The option socketPort must be supplied for socketType 'tcp'.");
        }
    }

    /**
     * Lqlの実行
     *
     * @param \Kwkm\MkLiveStatusClient\Lql $lql
     * @return array
     * @throw \RuntimeException
     */
    public function execute(Lql $lql)
    {
        $this->openSocket();
        $query = $lql->build();
        // Send the query to MK Livestatus
        socket_write($this->socket, $query);
        // Read 16 bytes to get the status code and body size
        $header = $this->readSocket(16);
        $status = substr($header, 0, 3);
        $length = intval(trim(substr($header, 4, 11)));
        $response = $this->readSocket($length);
        $this->closeSocket();

        // Check for errors. A 200 response means request was OK.
        // Any other response is a failure.
        if ($status != "200") {
            throw new RuntimeException("Error response from Nagios MK Livestatus: " . $response);
        }

        $response = json_decode(utf8_encode($response));

        if (is_null($response)) {
            throw new RuntimeException("The response was invalid.");
        }

        return $response;
    }

    /**<commit_msg>Division of methods.<commit_after><?php
/**
 * MkLiveStatusClient - Client
 *
 * @author <NAME> <<EMAIL>>
 * @license MIT
 */
namespace Kwkm\MkLiveStatusClient;

use \BadFunctionCallException;
use \InvalidArgumentException;
use \RuntimeException;

/**
 * Class Client
 * @package Kwkm\MkLiveStatusClient
 */
class Client
{
    /**
     * 接続方式(unix or tcp)
     * @var string
     */
    protected $socketType = "unix";

    /**
     * ソケットファイル
     * @var string
     */
    protected $socketPath = "/var/run/nagios/rw/live";

    /**
     * TCP接続時のIPアドレス
     * @var string
     */
    protected $socketAddress = "";

    /**
     * TCP接続時のポート
     * @var string
     */
    protected $socketPort = "";

    /**
     * TCP接続時のタイムアウト秒数
     * @var array
     * @link http://php.net/manual/en/function.socket-set-option.php
     */
    protected $socketTimeout = array();

    /**
     * ソケットのリソース
     * @var resource
     */
    protected $socket = null;

    /**
     * コンストラクタ
     *
     * @param array $conf
     * @throw \BadFunctionCallException
     * @throw \InvalidArgumentException
     */
    public function __construct(array $conf)
    {
        if (!function_exists("socket_create")) {
            throw new BadFunctionCallException("The PHP function socket_create is not available.");
        }

        $this->assignProperty($conf);

        $this->validateProperty();

        $this->reset();
    }

    /**
     * 設定をプロパティに割り当て
     *
     * @param array $conf
     */
    private function assignProperty($conf)
    {
        foreach ($conf as $key => $value) {
            if (property_exists($this, $key)) {
                $this->{$key} = $value;
            } else {
                throw new InvalidArgumentException("The option '$key' is not recognised.");
            }
        }
    }

    /**
     * プロパティの値の妥当性を確認
     */
    private function validateProperty()
    {
        switch ($this->socketType) {
            case "unix":
                $this->validatePropetrySocketPath();
                $this->checkAccessSocketPath();
                break;
            case "tcp":
                $this->validatePropetrySocketAddress();
                $this->validatePropetrySocketPort();
                break;
            default:
                throw new InvalidArgumentException("Socket Type is invalid. Must be one of 'unix' or 'tcp'.");
        }
    }

    private function validatePropetrySocketPath()
    {
        if (strlen($this->socketPath) === 0) {
            throw new InvalidArgumentException("The option socketPath must be supplied for socketType 'unix'.");
        }
    }

    private function checkAccessSocketPath()
    {
        if (!file_exists($this->socketPath) || !is_readable($this->socketPath) || !is_writable($this->socketPath)) {
            throw new InvalidArgumentException("The supplied socketPath '{$this->socketPath}' is not accessible to this script.");
        }
    }

    private function validatePropetrySocketAddress()
    {
        if (strlen($this->socketAddress) === 0) {
            throw new InvalidArgumentException("The option socketAddress must be supplied for socketType 'tcp'.");
        }
    }

    private function validatePropetrySocketPort()
    {
        if (strlen($this->socketPort) === 0) {
            throw new InvalidArgumentException("The option socketPort must be supplied for socketType 'tcp'.");
        }
    }

    /**
     * Lqlの実行
     *
     * @param \Kwkm\MkLiveStatusClient\Lql $lql
     * @return array
     * @throw \RuntimeException
     */
    public function execute(Lql $lql)
    {
        $result = $this->executeRequest($lql->build());

        $this->verifyStatusCode($result);

        $response = json_decode(utf8_encode($result['response']));

        if (is_null($response)) {
            throw new RuntimeException("The response was invalid.");
        }

        return $response;
    }

    private function executeRequest($query)
    {
        $this->openSocket();
        socket_write($this->socket, $query);
        // Read 16 bytes to get the status code and body size
        $header = $this->readSocket(16);
        $status = substr($header, 0, 3);
        $length = intval(trim(substr($header, 4, 11)));
        $response = $this->readSocket($length);
        $this->closeSocket();

        return array(
            'status' => $status,
            'length' => $length,
            'response' => $response,
        );
    }

    private function verifyStatusCode($response)
    {
        // Check for errors. A 200 response means request was OK.
        // Any other response is a failure.
        if ($response['status'] != "200") {
            throw new RuntimeException("Error response from Nagios MK Livestatus: " . $response['response']);
        }
    }

    /**
{'fraction_non_alphanumeric': 0.12764564695614228, 'fraction_numerical': 0.0041457560549858176, 'mean_word_length': 2.034425686858656, 'pattern_counts': {'":': 4, '<': 11, '<?xml version=': 0, '>': 59, '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': '1067819', 'n_tokens_mistral': 2726, 'n_tokens_neox': 2623, 'n_words': 605}