<?php
/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

namespace Grpc;

/**
 * Base class for generated client stubs. Stub methods are expected to call
 * _simpleRequest or _streamRequest and return the result.
 */
class BaseStub
{
    private $hostname;
    private $hostname_override;
    private $channel;
    private $call_invoker;

    // a callback function
    private $update_metadata;

    /**
     * @param string  $hostname
     * @param array   $opts
     *  - 'update_metadata': (optional) a callback function which takes in a
     * metadata array, and returns an updated metadata array
     *  - 'grpc.primary_user_agent': (optional) a user-agent string
     * @param Channel|InterceptorChannel $channel An already created Channel or InterceptorChannel object (optional)
     */
    public function __construct($hostname, $opts, $channel = null)
    {
        if (!method_exists('Grpc\ChannelCredentials', 'isDefaultRootsPemSet') ||
            !ChannelCredentials::isDefaultRootsPemSet()) {
            $ssl_roots = file_get_contents(
                dirname(__FILE__).'/../../../../etc/roots.pem'
            );
            ChannelCredentials::setDefaultRootsPem($ssl_roots);
        }

        $this->hostname = $hostname;
        $this->update_metadata = null;
        if (isset($opts['update_metadata'])) {
            if (is_callable($opts['update_metadata'])) {
                $this->update_metadata = $opts['update_metadata'];
            }
            unset($opts['update_metadata']);
        }
        if (!empty($opts['grpc.ssl_target_name_override'])) {
            $this->hostname_override = $opts['grpc.ssl_target_name_override'];
        }
        if (isset($opts['grpc_call_invoker'])) {
            $this->call_invoker = $opts['grpc_call_invoker'];
            unset($opts['grpc_call_invoker']);
            $channel_opts = $this->updateOpts($opts);
            // If the grpc_call_invoker is defined, use the channel created by the call invoker.
            $this->channel = $this->call_invoker->createChannelFactory($hostname, $channel_opts);
            return;
        }
        $this->call_invoker = new DefaultCallInvoker();
        if ($channel) {
            if (!is_a($channel, 'Grpc\Channel') &&
                !is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
                throw new \Exception('The channel argument is not a Channel object '.
                    'or an InterceptorChannel object created by '.
                    'Interceptor::intercept($channel, Interceptor|Interceptor[] $interceptors)');
            }
            $this->channel = $channel;
            return;
        }

        $this->channel = static::getDefaultChannel($hostname, $opts);
    }

    private static function updateOpts($opts) {
        if (!empty($opts['grpc.primary_user_agent'])) {
            $opts['grpc.primary_user_agent'] .= ' ';
        } else {
            $opts['grpc.primary_user_agent'] = '';
        }
        if (defined('\Grpc\VERSION')) {
            $version_str = \Grpc\VERSION;
        } else {
            if (!file_exists($composerFile = __DIR__.'/../../composer.json')) {
                // for grpc/grpc-php subpackage
                $composerFile = __DIR__.'/../composer.json';
            }
            $package_config = json_decode(file_get_contents($composerFile), true);
            $version_str = $package_config['version'];
        }
        $opts['grpc.primary_user_agent'] .= 'grpc-php/'.$version_str;
        if (!array_key_exists('credentials', $opts)) {
            throw new \Exception("The opts['credentials'] key is now ".
                'required. Please see one of the '.
                'ChannelCredentials::create methods');
        }
        return $opts;
    }

    /**
     * Creates and returns the default Channel
     *
     * @param array $opts Channel constructor options
     *
     * @return Channel The channel
     */
    public static function getDefaultChannel($hostname, array $opts)
    {
        $channel_opts = self::updateOpts($opts);
        return new Channel($hostname, $channel_opts);
    }

    /**
     * @return string The URI of the endpoint
     */
    public function getTarget()
    {
        return $this->channel->getTarget();
    }

    /**
     * @param bool $try_to_connect (optional)
     *
     * @return int The grpc connectivity state
     */
    public function getConnectivityState($try_to_connect = false)
    {
        return $this->channel->getConnectivityState($try_to_connect);
    }

    /**
     * @param int $timeout in microseconds
     *
     * @return bool true if channel is ready
     * @throws Exception if channel is in FATAL_ERROR state
     */
    public function waitForReady($timeout)
    {
        $new_state = $this->getConnectivityState(true);
        if ($this->_checkConnectivityState($new_state)) {
            return true;
        }

        $now = Timeval::now();
        $delta = new Timeval($timeout);
        $deadline = $now->add($delta);

        while ($this->channel->watchConnectivityState($new_state, $deadline)) {
            // state has changed before deadline
            $new_state = $this->getConnectivityState();
            if ($this->_checkConnectivityState($new_state)) {
                return true;
            }
        }
        // deadline has passed
        $new_state = $this->getConnectivityState();

        return $this->_checkConnectivityState($new_state);
    }

    /**
     * Close the communication channel associated with this stub.
     */
    public function close()
    {
        $this->channel->close();
    }

    /**
     * @param $new_state Connect state
     *
     * @return bool true if state is CHANNEL_READY
     * @throws Exception if state is CHANNEL_FATAL_FAILURE
     */
    private function _checkConnectivityState($new_state)
    {
        if ($new_state == \Grpc\CHANNEL_READY) {
            return true;
        }
        if ($new_state == \Grpc\CHANNEL_FATAL_FAILURE) {
            throw new \Exception('Failed to connect to server');
        }

        return false;
    }

    /**
     * constructs the auth uri for the jwt.
     *
     * @param string $method The method string
     *
     * @return string The URL string
     */
    private function _get_jwt_aud_uri($method)
    {
        // TODO(jtattermusch): This is not the correct implementation
        // of extracting JWT "aud" claim. We should rely on
        // grpc_metadata_credentials_plugin which
        // also provides the correct value of "aud" claim
        // in the grpc_auth_metadata_context.service_url field.
        // Trying to do the construction of "aud" field ourselves
        // is bad.
        $last_slash_idx = strrpos($method, '/');
        if ($last_slash_idx === false) {
            throw new \InvalidArgumentException(
                'service name must have a slash'
            );
        }
        $service_name = substr($method, 0, $last_slash_idx);

        if ($this->hostname_override) {
            $hostname = $this->hostname_override;
        } else {
            $hostname = $this->hostname;
        }

        // Remove the port if it is 443
        // See https://github.com/grpc/grpc/blob/07c9f7a36b2a0d34fcffebc85649cf3b8c339b5d/src/core/filter/auth/client_auth_filter.cc#L205
        if ((strlen($hostname) > 4) && (substr($hostname, -4) === ":443")) {
            $hostname = substr($hostname, 0, -4);
        }

        return 'https://'.$hostname.$service_name;
    }

    /**
     * validate and normalize the metadata array.
     *
     * @param array $metadata The metadata map
     *
     * @return array $metadata Validated and key-normalized metadata map
     * @throws InvalidArgumentException if key contains invalid characters
     */
    private function _validate_and_normalize_metadata($metadata)
    {
        $metadata_copy = [];
        foreach ($metadata as $key => $value) {
            if (!preg_match('/^[.A-Za-z\d_-]+$/', $key)) {
                throw new \InvalidArgumentException(
                    'Metadata keys must be nonempty strings containing only '.
                    'alphanumeric characters, hyphens, underscores and dots'
                );
            }
            $metadata_copy[strtolower($key)] = $value;
        }

        return $metadata_copy;
    }

    /**
     * Create a function which can be used to create UnaryCall
     *
     * @param Channel|InterceptorChannel   $channel
     * @param callable $deserialize A function that deserializes the response
     *
     * @return \Closure
     */
    private function _GrpcUnaryUnary($channel)
    {
        return function ($method,
                         $argument,
                         $deserialize,
                         array $metadata = [],
                         array $options = []) use ($channel) {
            $call = $this->call_invoker->UnaryCall(
                $channel,
                $method,
                $deserialize,
                $options
            );
            $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
            if (is_callable($this->update_metadata)) {
                $metadata = call_user_func(
                    $this->update_metadata,
                    $metadata,
                    $jwt_aud_uri
                );
            }
            $metadata = $this->_validate_and_normalize_metadata(
                $metadata
            );
            $call->start($argument, $metadata, $options);
            return $call;
        };
    }

    /**
     * Create a function which can be used to create ServerStreamingCall
     *
     * @param Channel|InterceptorChannel   $channel
     * @param callable $deserialize A function that deserializes the response
     *
     * @return \Closure
     */
    private function _GrpcStreamUnary($channel)
    {
        return function ($method,
                         $deserialize,
                         array $metadata = [],
                         array $options = []) use ($channel) {
            $call = $this->call_invoker->ClientStreamingCall(
                $channel,
                $method,
                $deserialize,
                $options
            );
            $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
            if (is_callable($this->update_metadata)) {
                $metadata = call_user_func(
                    $this->update_metadata,
                    $metadata,
                    $jwt_aud_uri
                );
            }
            $metadata = $this->_validate_and_normalize_metadata(
                $metadata
            );
            $call->start($metadata);
            return $call;
        };
    }

    /**
     * Create a function which can be used to create ClientStreamingCall
     *
     * @param Channel|InterceptorChannel   $channel
     * @param callable $deserialize A function that deserializes the response
     *
     * @return \Closure
     */
    private function _GrpcUnaryStream($channel)
    {
        return function ($method,
                         $argument,
                         $deserialize,
                         array $metadata = [],
                         array $options = []) use ($channel) {
            $call = $this->call_invoker->ServerStreamingCall(
                $channel,
                $method,
                $deserialize,
                $options
            );
            $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
            if (is_callable($this->update_metadata)) {
                $metadata = call_user_func(
                    $this->update_metadata,
                    $metadata,
                    $jwt_aud_uri
                );
            }
            $metadata = $this->_validate_and_normalize_metadata(
                $metadata
            );
            $call->start($argument, $metadata, $options);
            return $call;
        };
    }

    /**
     * Create a function which can be used to create BidiStreamingCall
     *
     * @param Channel|InterceptorChannel   $channel
     * @param callable $deserialize A function that deserializes the response
     *
     * @return \Closure
     */
    private function _GrpcStreamStream($channel)
    {
        return function ($method,
                         $deserialize,
                         array $metadata = [],
                         array $options = []) use ($channel) {
            $call = $this->call_invoker->BidiStreamingCall(
                $channel,
                $method,
                $deserialize,
                $options
            );
            $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
            if (is_callable($this->update_metadata)) {
                $metadata = call_user_func(
                    $this->update_metadata,
                    $metadata,
                    $jwt_aud_uri
                );
            }
            $metadata = $this->_validate_and_normalize_metadata(
                $metadata
            );
            $call->start($metadata);

            return $call;
        };
    }

    /**
     * Create a function which can be used to create UnaryCall
     *
     * @param Channel|InterceptorChannel   $channel
     * @param callable $deserialize A function that deserializes the response
     *
     * @return \Closure
     */
    private function _UnaryUnaryCallFactory($channel)
    {
        if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
            return function ($method,
                             $argument,
                             $deserialize,
                             array $metadata = [],
                             array $options = []) use ($channel) {
                return $channel->getInterceptor()->interceptUnaryUnary(
                    $method,
                    $argument,
                    $deserialize,
                    $this->_UnaryUnaryCallFactory($channel->getNext()),
                    $metadata,
                    $options
                );
            };
        }
        return $this->_GrpcUnaryUnary($channel);
    }

    /**
     * Create a function which can be used to create ServerStreamingCall
     *
     * @param Channel|InterceptorChannel   $channel
     * @param callable $deserialize A function that deserializes the response
     *
     * @return \Closure
     */
    private function _UnaryStreamCallFactory($channel)
    {
        if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
            return function ($method,
                             $argument,
                             $deserialize,
                             array $metadata = [],
                             array $options = []) use ($channel) {
                return $channel->getInterceptor()->interceptUnaryStream(
                    $method,
                    $argument,
                    $deserialize,
                    $this->_UnaryStreamCallFactory($channel->getNext()),
                    $metadata,
                    $options
                );
            };
        }
        return $this->_GrpcUnaryStream($channel);
    }

    /**
     * Create a function which can be used to create ClientStreamingCall
     *
     * @param Channel|InterceptorChannel   $channel
     * @param callable $deserialize A function that deserializes the response
     *
     * @return \Closure
     */
    private function _StreamUnaryCallFactory($channel)
    {
        if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
            return function ($method,
                             $deserialize,
                             array $metadata = [],
                             array $options = []) use ($channel) {
                return $channel->getInterceptor()->interceptStreamUnary(
                    $method,
                    $deserialize,
                    $this->_StreamUnaryCallFactory($channel->getNext()),
                    $metadata,
                    $options
                );
            };
        }
        return $this->_GrpcStreamUnary($channel);
    }

    /**
     * Create a function which can be used to create BidiStreamingCall
     *
     * @param Channel|InterceptorChannel   $channel
     * @param callable $deserialize A function that deserializes the response
     *
     * @return \Closure
     */
    private function _StreamStreamCallFactory($channel)
    {
        if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
            return function ($method,
                             $deserialize,
                             array $metadata = [],
                             array $options = []) use ($channel) {
                return $channel->getInterceptor()->interceptStreamStream(
                    $method,
                    $deserialize,
                    $this->_StreamStreamCallFactory($channel->getNext()),
                    $metadata,
                    $options
                );
            };
        }
        return $this->_GrpcStreamStream($channel);
    }

    /* This class is intended to be subclassed by generated code, so
     * all functions begin with "_" to avoid name collisions. */
    /**
     * Call a remote method that takes a single argument and has a
     * single output.
     *
     * @param string   $method      The name of the method to call
     * @param mixed    $argument    The argument to the method
     * @param callable $deserialize A function that deserializes the response
     * @param array    $metadata    A metadata map to send to the server
     *                              (optional)
     * @param array    $options     An array of options (optional)
     *
     * @return UnaryCall The active call object
     */
    protected function _simpleRequest(
        $method,
        $argument,
        $deserialize,
        array $metadata = [],
        array $options = []
    ) {
        $call_factory = $this->_UnaryUnaryCallFactory($this->channel);
        $call = $call_factory($method, $argument, $deserialize, $metadata, $options);
        return $call;
    }

    /**
     * Call a remote method that takes a stream of arguments and has a single
     * output.
     *
     * @param string   $method      The name of the method to call
     * @param callable $deserialize A function that deserializes the response
     * @param array    $metadata    A metadata map to send to the server
     *                              (optional)
     * @param array    $options     An array of options (optional)
     *
     * @return ClientStreamingCall The active call object
     */
    protected function _clientStreamRequest(
        $method,
        $deserialize,
        array $metadata = [],
        array $options = []
    ) {
        $call_factory = $this->_StreamUnaryCallFactory($this->channel);
        $call = $call_factory($method, $deserialize, $metadata, $options);
        return $call;
    }

    /**
     * Call a remote method that takes a single argument and returns a stream
     * of responses.
     *
     * @param string   $method      The name of the method to call
     * @param mixed    $argument    The argument to the method
     * @param callable $deserialize A function that deserializes the responses
     * @param array    $metadata    A metadata map to send to the server
     *                              (optional)
     * @param array    $options     An array of options (optional)
     *
     * @return ServerStreamingCall The active call object
     */
    protected function _serverStreamRequest(
        $method,
        $argument,
        $deserialize,
        array $metadata = [],
        array $options = []
    ) {
        $call_factory = $this->_UnaryStreamCallFactory($this->channel);
        $call = $call_factory($method, $argument, $deserialize, $metadata, $options);
        return $call;
    }

    /**
     * Call a remote method with messages streaming in both directions.
     *
     * @param string   $method      The name of the method to call
     * @param callable $deserialize A function that deserializes the responses
     * @param array    $metadata    A metadata map to send to the server
     *                              (optional)
     * @param array    $options     An array of options (optional)
     *
     * @return BidiStreamingCall The active call object
     */
    protected function _bidiRequest(
        $method,
        $deserialize,
        array $metadata = [],
        array $options = []
    ) {
        $call_factory = $this->_StreamStreamCallFactory($this->channel);
        $call = $call_factory($method, $deserialize, $metadata, $options);
        return $call;
    }
}
