<?php
/*
 *
 * Copyright 2018 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.
 *
 */
/**
 * Interface exported by the server.
 */
require_once(dirname(__FILE__).'/../../lib/Grpc/BaseStub.php');
require_once(dirname(__FILE__).'/../../lib/Grpc/AbstractCall.php');
require_once(dirname(__FILE__).'/../../lib/Grpc/UnaryCall.php');
require_once(dirname(__FILE__).'/../../lib/Grpc/ClientStreamingCall.php');
require_once(dirname(__FILE__).'/../../lib/Grpc/Interceptor.php');
require_once(dirname(__FILE__).'/../../lib/Grpc/CallInvoker.php');
require_once(dirname(__FILE__).'/../../lib/Grpc/DefaultCallInvoker.php');
require_once(dirname(__FILE__).'/../../lib/Grpc/Internal/InterceptorChannel.php');

class CallInvokerSimpleRequest
{
    private $data;
    public function __construct($data)
    {
        $this->data = $data;
    }
    public function setData($data)
    {
        $this->data = $data;
    }
    public function serializeToString()
    {
        return $this->data;
    }
}

class CallInvokerClient extends Grpc\BaseStub
{

  /**
   * @param string $hostname hostname
   * @param array $opts channel options
   * @param Channel|InterceptorChannel $channel (optional) re-use channel object
   */
  public function __construct($hostname, $opts, $channel = null)
  {
    parent::__construct($hostname, $opts, $channel);
  }

  /**
   * A simple RPC.
   * @param SimpleRequest $argument input argument
   * @param array $metadata metadata
   * @param array $options call options
   */
  public function UnaryCall(
    CallInvokerSimpleRequest $argument,
    $metadata = [],
    $options = []
  ) {
    return $this->_simpleRequest(
      '/dummy_method',
      $argument,
      [],
      $metadata,
      $options
    );
  }
}

class CallInvokerUpdateChannel implements \Grpc\CallInvoker
{
    private $channel;

    public function getChannel() {
        return $this->channel;
    }

    public function createChannelFactory($hostname, $opts) {
        $this->channel = new \Grpc\Channel('localhost:50050', $opts);
        return $this->channel;
    }

    public function UnaryCall($channel, $method, $deserialize, $options) {
        return new UnaryCall($channel, $method, $deserialize, $options);
    }

    public function ClientStreamingCall($channel, $method, $deserialize, $options) {
        return new ClientStreamingCall($channel, $method, $deserialize, $options);
    }

    public function ServerStreamingCall($channel, $method, $deserialize, $options) {
        return new ServerStreamingCall($channel, $method, $deserialize, $options);
    }

    public function BidiStreamingCall($channel, $method, $deserialize, $options) {
        return new BidiStreamingCall($channel, $method, $deserialize, $options);
    }
}


class CallInvokerChangeRequest implements \Grpc\CallInvoker
{
    private $channel;

    public function getChannel() {
        return $this->channel;
    }
    public function createChannelFactory($hostname, $opts) {
        $this->channel = new \Grpc\Channel($hostname, $opts);
        return $this->channel;
    }

    public function UnaryCall($channel, $method, $deserialize, $options) {
        return new CallInvokerChangeRequestCall($channel, $method, $deserialize, $options);
    }

    public function ClientStreamingCall($channel, $method, $deserialize, $options) {
        return new ClientStreamingCall($channel, $method, $deserialize, $options);
    }

    public function ServerStreamingCall($channel, $method, $deserialize, $options) {
        return new ServerStreamingCall($channel, $method, $deserialize, $options);
    }

    public function BidiStreamingCall($channel, $method, $deserialize, $options) {
        return new BidiStreamingCall($channel, $method, $deserialize, $options);
    }
}

class CallInvokerChangeRequestCall
{
    private $call;

    public function __construct($channel, $method, $deserialize, $options)
    {
        $this->call = new \Grpc\UnaryCall($channel, $method, $deserialize, $options);
    }

    public function start($argument, $metadata, $options) {
        $argument->setData('intercepted_unary_request');
        $this->call->start($argument, $metadata, $options);
    }

    public function wait()
    {
        return $this->call->wait();
    }
}

class CallInvokerTest extends PHPUnit_Framework_TestCase
{
    public function setUp()
    {
        $this->server = new Grpc\Server([]);
        $this->port = $this->server->addHttp2Port('0.0.0.0:0');
        $this->server->start();
    }

    public function tearDown()
    {
        unset($this->server);
    }

    public function testCreateDefaultCallInvoker()
    {
        $call_invoker = new \Grpc\DefaultCallInvoker();
    }

    public function testCreateCallInvoker()
    {
        $call_invoker = new CallInvokerUpdateChannel();
    }

    public function testCallInvokerAccessChannel()
    {
        $call_invoker = new CallInvokerUpdateChannel();
        $stub = new \Grpc\BaseStub('localhost:50051',
          ['credentials' => \Grpc\ChannelCredentials::createInsecure(),
            'grpc_call_invoker' => $call_invoker]);
        $this->assertEquals($call_invoker->getChannel()->getTarget(), 'localhost:50050');
        $call_invoker->getChannel()->close();
    }

    public function testClientChangeRequestCallInvoker()
    {
        $req_text = 'client_request';
        $call_invoker = new CallInvokerChangeRequest();
        $client = new CallInvokerClient('localhost:'.$this->port, [
            'force_new' => true,
            'credentials' => Grpc\ChannelCredentials::createInsecure(),
            'grpc_call_invoker' => $call_invoker,
        ]);

        $req = new CallInvokerSimpleRequest($req_text);
        $unary_call = $client->UnaryCall($req);

        $event = $this->server->requestCall();
        $this->assertSame('/dummy_method', $event->method);
        $server_call = $event->call;
        $event = $server_call->startBatch([
            Grpc\OP_SEND_INITIAL_METADATA => [],
            Grpc\OP_SEND_STATUS_FROM_SERVER => [
                'metadata' => [],
                'code' => Grpc\STATUS_OK,
                'details' => '',
            ],
            Grpc\OP_RECV_MESSAGE => true,
            Grpc\OP_RECV_CLOSE_ON_SERVER => true,
        ]);
        $this->assertSame('intercepted_unary_request', $event->message);
        $call_invoker->getChannel()->close();
        unset($unary_call);
        unset($server_call);
    }
}
