<?php
/*
 *
 * Copyright 2015-2016 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.
 *
 */
require_once realpath(dirname(__FILE__).'/../../vendor/autoload.php');

// The following includes are needed when using protobuf 3.1.0
// and will suppress warnings when using protobuf 3.2.0+
@include_once 'src/proto/grpc/testing/test.pb.php';
@include_once 'src/proto/grpc/testing/test_grpc_pb.php';

use Google\Auth\CredentialsLoader;
use Google\Auth\ApplicationDefaultCredentials;
use GuzzleHttp\ClientInterface;

/**
 * Assertion function that always exits with an error code if the assertion is
 * falsy.
 *
 * @param $value Assertion value. Should be true.
 * @param $error_message Message to display if the assertion is false
 */
function hardAssert($value, $error_message)
{
    if (!$value) {
        echo $error_message."\n";
        exit(1);
    }
}

function hardAssertIfStatusOk($status)
{
    if ($status->code !== Grpc\STATUS_OK) {
        echo "Call did not complete successfully. Status object:\n";
        var_dump($status);
        exit(1);
    }
}

/**
 * Run the empty_unary test.
 *
 * @param $stub Stub object that has service methods
 */
function emptyUnary($stub)
{
    list($result, $status) =
        $stub->EmptyCall(new Grpc\Testing\EmptyMessage())->wait();
    hardAssertIfStatusOk($status);
    hardAssert($result !== null, 'Call completed with a null response');
}

/**
 * Run the large_unary test.
 *
 * @param $stub Stub object that has service methods
 */
function largeUnary($stub)
{
    performLargeUnary($stub);
}

/**
 * Shared code between large unary test and auth test.
 *
 * @param $stub Stub object that has service methods
 * @param $fillUsername boolean whether to fill result with username
 * @param $fillOauthScope boolean whether to fill result with oauth scope
 */
function performLargeUnary($stub, $fillUsername = false,
                           $fillOauthScope = false, $callback = false)
{
    $request_len = 271828;
    $response_len = 314159;

    $request = new Grpc\Testing\SimpleRequest();
    $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
    $request->setResponseSize($response_len);
    $payload = new Grpc\Testing\Payload();
    $payload->setType(Grpc\Testing\PayloadType::COMPRESSABLE);
    $payload->setBody(str_repeat("\0", $request_len));
    $request->setPayload($payload);
    $request->setFillUsername($fillUsername);
    $request->setFillOauthScope($fillOauthScope);

    $options = [];
    if ($callback) {
        $options['call_credentials_callback'] = $callback;
    }

    list($result, $status) = $stub->UnaryCall($request, [], $options)->wait();
    hardAssertIfStatusOk($status);
    hardAssert($result !== null, 'Call returned a null response');
    $payload = $result->getPayload();
    hardAssert($payload->getType() === Grpc\Testing\PayloadType::COMPRESSABLE,
               'Payload had the wrong type');
    hardAssert(strlen($payload->getBody()) === $response_len,
               'Payload had the wrong length');
    hardAssert($payload->getBody() === str_repeat("\0", $response_len),
               'Payload had the wrong content');

    return $result;
}

/**
 * Run the service account credentials auth test.
 *
 * @param $stub Stub object that has service methods
 * @param $args array command line args
 */
function serviceAccountCreds($stub, $args)
{
    if (!array_key_exists('oauth_scope', $args)) {
        throw new Exception('Missing oauth scope');
    }
    $jsonKey = json_decode(
        file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
        true);
    $result = performLargeUnary($stub, $fillUsername = true,
                                $fillOauthScope = true);
    hardAssert($result->getUsername() === $jsonKey['client_email'],
               'invalid email returned');
    hardAssert(strpos($args['oauth_scope'], $result->getOauthScope()) !== false,
               'invalid oauth scope returned');
}

/**
 * Run the compute engine credentials auth test.
 * Has not been run from gcloud as of 2015-05-05.
 *
 * @param $stub Stub object that has service methods
 * @param $args array command line args
 */
function computeEngineCreds($stub, $args)
{
    if (!array_key_exists('oauth_scope', $args)) {
        throw new Exception('Missing oauth scope');
    }
    if (!array_key_exists('default_service_account', $args)) {
        throw new Exception('Missing default_service_account');
    }
    $result = performLargeUnary($stub, $fillUsername = true,
                                $fillOauthScope = true);
    hardAssert($args['default_service_account'] === $result->getUsername(),
               'invalid email returned');
}

/**
 * Run the jwt token credentials auth test.
 *
 * @param $stub Stub object that has service methods
 * @param $args array command line args
 */
function jwtTokenCreds($stub, $args)
{
    $jsonKey = json_decode(
        file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
        true);
    $result = performLargeUnary($stub, $fillUsername = true,
                                $fillOauthScope = true);
    hardAssert($result->getUsername() === $jsonKey['client_email'],
               'invalid email returned');
}

/**
 * Run the oauth2_auth_token auth test.
 *
 * @param $stub Stub object that has service methods
 * @param $args array command line args
 */
function oauth2AuthToken($stub, $args)
{
    $jsonKey = json_decode(
        file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
        true);
    $result = performLargeUnary($stub, $fillUsername = true,
                                $fillOauthScope = true);
    hardAssert($result->getUsername() === $jsonKey['client_email'],
               'invalid email returned');
}

function updateAuthMetadataCallback($context)
{
    $authUri = $context->service_url;
    $methodName = $context->method_name;
    $auth_credentials = ApplicationDefaultCredentials::getCredentials();

    $metadata = [];
    $result = $auth_credentials->updateMetadata([], $authUri);
    foreach ($result as $key => $value) {
        $metadata[strtolower($key)] = $value;
    }

    return $metadata;
}

/**
 * Run the per_rpc_creds auth test.
 *
 * @param $stub Stub object that has service methods
 * @param $args array command line args
 */
function perRpcCreds($stub, $args)
{
    $jsonKey = json_decode(
        file_get_contents(getenv(CredentialsLoader::ENV_VAR)),
        true);

    $result = performLargeUnary($stub, $fillUsername = true,
                                $fillOauthScope = true,
                                'updateAuthMetadataCallback');
    hardAssert($result->getUsername() === $jsonKey['client_email'],
               'invalid email returned');
}

/**
 * Run the client_streaming test.
 *
 * @param $stub Stub object that has service methods
 */
function clientStreaming($stub)
{
    $request_lengths = [27182, 8, 1828, 45904];

    $requests = array_map(
        function ($length) {
            $request = new Grpc\Testing\StreamingInputCallRequest();
            $payload = new Grpc\Testing\Payload();
            $payload->setBody(str_repeat("\0", $length));
            $request->setPayload($payload);

            return $request;
        }, $request_lengths);

    $call = $stub->StreamingInputCall();
    foreach ($requests as $request) {
        $call->write($request);
    }
    list($result, $status) = $call->wait();
    hardAssertIfStatusOk($status);
    hardAssert($result->getAggregatedPayloadSize() === 74922,
               'aggregated_payload_size was incorrect');
}

/**
 * Run the server_streaming test.
 *
 * @param $stub Stub object that has service methods.
 */
function serverStreaming($stub)
{
    $sizes = [31415, 9, 2653, 58979];

    $request = new Grpc\Testing\StreamingOutputCallRequest();
    $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
    foreach ($sizes as $size) {
        $response_parameters = new Grpc\Testing\ResponseParameters();
        $response_parameters->setSize($size);
        $request->getResponseParameters()[] = $response_parameters;
    }

    $call = $stub->StreamingOutputCall($request);
    $i = 0;
    foreach ($call->responses() as $value) {
        hardAssert($i < 4, 'Too many responses');
        $payload = $value->getPayload();
        hardAssert(
            $payload->getType() === Grpc\Testing\PayloadType::COMPRESSABLE,
            'Payload '.$i.' had the wrong type');
        hardAssert(strlen($payload->getBody()) === $sizes[$i],
                   'Response '.$i.' had the wrong length');
        $i += 1;
    }
    hardAssertIfStatusOk($call->getStatus());
}

/**
 * Run the ping_pong test.
 *
 * @param $stub Stub object that has service methods.
 */
function pingPong($stub)
{
    $request_lengths = [27182, 8, 1828, 45904];
    $response_lengths = [31415, 9, 2653, 58979];

    $call = $stub->FullDuplexCall();
    for ($i = 0; $i < 4; ++$i) {
        $request = new Grpc\Testing\StreamingOutputCallRequest();
        $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
        $response_parameters = new Grpc\Testing\ResponseParameters();
        $response_parameters->setSize($response_lengths[$i]);
        $request->getResponseParameters()[] = $response_parameters;
        $payload = new Grpc\Testing\Payload();
        $payload->setBody(str_repeat("\0", $request_lengths[$i]));
        $request->setPayload($payload);

        $call->write($request);
        $response = $call->read();

        hardAssert($response !== null, 'Server returned too few responses');
        $payload = $response->getPayload();
        hardAssert(
            $payload->getType() === Grpc\Testing\PayloadType::COMPRESSABLE,
            'Payload '.$i.' had the wrong type');
        hardAssert(strlen($payload->getBody()) === $response_lengths[$i],
                   'Payload '.$i.' had the wrong length');
    }
    $call->writesDone();
    hardAssert($call->read() === null, 'Server returned too many responses');
    hardAssertIfStatusOk($call->getStatus());
}

/**
 * Run the empty_stream test.
 *
 * @param $stub Stub object that has service methods.
 */
function emptyStream($stub)
{
    $call = $stub->FullDuplexCall();
    $call->writesDone();
    hardAssert($call->read() === null, 'Server returned too many responses');
    hardAssertIfStatusOk($call->getStatus());
}

/**
 * Run the cancel_after_begin test.
 *
 * @param $stub Stub object that has service methods.
 */
function cancelAfterBegin($stub)
{
    $call = $stub->StreamingInputCall();
    $call->cancel();
    list($result, $status) = $call->wait();
    hardAssert($status->code === Grpc\STATUS_CANCELLED,
               'Call status was not CANCELLED');
}

/**
 * Run the cancel_after_first_response test.
 *
 * @param $stub Stub object that has service methods.
 */
function cancelAfterFirstResponse($stub)
{
    $call = $stub->FullDuplexCall();
    $request = new Grpc\Testing\StreamingOutputCallRequest();
    $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
    $response_parameters = new Grpc\Testing\ResponseParameters();
    $response_parameters->setSize(31415);
    $request->getResponseParameters()[] = $response_parameters;
    $payload = new Grpc\Testing\Payload();
    $payload->setBody(str_repeat("\0", 27182));
    $request->setPayload($payload);

    $call->write($request);
    $response = $call->read();

    $call->cancel();
    hardAssert($call->getStatus()->code === Grpc\STATUS_CANCELLED,
               'Call status was not CANCELLED');
}

function timeoutOnSleepingServer($stub)
{
    $call = $stub->FullDuplexCall([], ['timeout' => 1000]);
    $request = new Grpc\Testing\StreamingOutputCallRequest();
    $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
    $response_parameters = new Grpc\Testing\ResponseParameters();
    $response_parameters->setSize(8);
    $request->getResponseParameters()[] = $response_parameters;
    $payload = new Grpc\Testing\Payload();
    $payload->setBody(str_repeat("\0", 9));
    $request->setPayload($payload);

    $call->write($request);
    $response = $call->read();

    hardAssert($call->getStatus()->code === Grpc\STATUS_DEADLINE_EXCEEDED,
               'Call status was not DEADLINE_EXCEEDED');
}

function customMetadata($stub)
{
    $ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
    $ECHO_INITIAL_VALUE = 'test_initial_metadata_value';
    $ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin';
    $ECHO_TRAILING_VALUE = 'ababab';
    $request_len = 271828;
    $response_len = 314159;

    $request = new Grpc\Testing\SimpleRequest();
    $request->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
    $request->setResponseSize($response_len);
    $payload = new Grpc\Testing\Payload();
    $payload->setType(Grpc\Testing\PayloadType::COMPRESSABLE);
    $payload->setBody(str_repeat("\0", $request_len));
    $request->setPayload($payload);

    $metadata = [
        $ECHO_INITIAL_KEY => [$ECHO_INITIAL_VALUE],
        $ECHO_TRAILING_KEY => [$ECHO_TRAILING_VALUE],
    ];
    $call = $stub->UnaryCall($request, $metadata);

    $initial_metadata = $call->getMetadata();
    hardAssert(array_key_exists($ECHO_INITIAL_KEY, $initial_metadata),
               'Initial metadata does not contain expected key');
    hardAssert(
        $initial_metadata[$ECHO_INITIAL_KEY][0] === $ECHO_INITIAL_VALUE,
        'Incorrect initial metadata value');

    list($result, $status) = $call->wait();
    hardAssertIfStatusOk($status);

    $trailing_metadata = $call->getTrailingMetadata();
    hardAssert(array_key_exists($ECHO_TRAILING_KEY, $trailing_metadata),
               'Trailing metadata does not contain expected key');
    hardAssert(
        $trailing_metadata[$ECHO_TRAILING_KEY][0] === $ECHO_TRAILING_VALUE,
        'Incorrect trailing metadata value');

    $streaming_call = $stub->FullDuplexCall($metadata);

    $streaming_request = new Grpc\Testing\StreamingOutputCallRequest();
    $streaming_request->setPayload($payload);
    $response_parameters = new Grpc\Testing\ResponseParameters();
    $response_parameters->setSize($response_len);
    $streaming_request->getResponseParameters()[] = $response_parameters;
    $streaming_call->write($streaming_request);
    $streaming_call->writesDone();
    $result = $streaming_call->read();

    hardAssertIfStatusOk($streaming_call->getStatus());

    $streaming_initial_metadata = $streaming_call->getMetadata();
    hardAssert(array_key_exists($ECHO_INITIAL_KEY, $streaming_initial_metadata),
               'Initial metadata does not contain expected key');
    hardAssert(
        $streaming_initial_metadata[$ECHO_INITIAL_KEY][0] === $ECHO_INITIAL_VALUE,
        'Incorrect initial metadata value');

    $streaming_trailing_metadata = $streaming_call->getTrailingMetadata();
    hardAssert(array_key_exists($ECHO_TRAILING_KEY,
                                $streaming_trailing_metadata),
               'Trailing metadata does not contain expected key');
    hardAssert($streaming_trailing_metadata[$ECHO_TRAILING_KEY][0] ===
               $ECHO_TRAILING_VALUE, 'Incorrect trailing metadata value');
}

function statusCodeAndMessage($stub)
{
    $echo_status = new Grpc\Testing\EchoStatus();
    $echo_status->setCode(2);
    $echo_status->setMessage('test status message');

    $request = new Grpc\Testing\SimpleRequest();
    $request->setResponseStatus($echo_status);

    $call = $stub->UnaryCall($request);
    list($result, $status) = $call->wait();

    hardAssert($status->code === 2,
               'Received unexpected UnaryCall status code: '.
               $status->code);
    hardAssert($status->details === 'test status message',
               'Received unexpected UnaryCall status details: '.
               $status->details);

    $streaming_call = $stub->FullDuplexCall();

    $streaming_request = new Grpc\Testing\StreamingOutputCallRequest();
    $streaming_request->setResponseStatus($echo_status);
    $streaming_call->write($streaming_request);
    $streaming_call->writesDone();
    $result = $streaming_call->read();

    $status = $streaming_call->getStatus();
    hardAssert($status->code === 2,
               'Received unexpected FullDuplexCall status code: '.
               $status->code);
    hardAssert($status->details === 'test status message',
               'Received unexpected FullDuplexCall status details: '.
               $status->details);
}

# NOTE: the stub input to this function is from UnimplementedService
function unimplementedService($stub)
{
    $call = $stub->UnimplementedCall(new Grpc\Testing\EmptyMessage());
    list($result, $status) = $call->wait();
    hardAssert($status->code === Grpc\STATUS_UNIMPLEMENTED,
               'Received unexpected status code');
}

# NOTE: the stub input to this function is from TestService
function unimplementedMethod($stub)
{
    $call = $stub->UnimplementedCall(new Grpc\Testing\EmptyMessage());
    list($result, $status) = $call->wait();
    hardAssert($status->code === Grpc\STATUS_UNIMPLEMENTED,
               'Received unexpected status code');
}

function _makeStub($args)
{
    if (!array_key_exists('server_host', $args)) {
        throw new Exception('Missing argument: --server_host is required');
    }
    if (!array_key_exists('server_port', $args)) {
        throw new Exception('Missing argument: --server_port is required');
    }
    if (!array_key_exists('test_case', $args)) {
        throw new Exception('Missing argument: --test_case is required');
    }

    if ($args['server_port'] === 443) {
        $server_address = $args['server_host'];
    } else {
        $server_address = $args['server_host'].':'.$args['server_port'];
    }

    $test_case = $args['test_case'];

    $host_override = 'foo.test.google.fr';
    if (array_key_exists('server_host_override', $args)) {
        $host_override = $args['server_host_override'];
    }

    $use_tls = false;
    if (array_key_exists('use_tls', $args) &&
        $args['use_tls'] != 'false') {
        $use_tls = true;
    }

    $use_test_ca = false;
    if (array_key_exists('use_test_ca', $args) &&
        $args['use_test_ca'] != 'false') {
        $use_test_ca = true;
    }

    $opts = [];

    if ($use_tls) {
        if ($use_test_ca) {
            $ssl_credentials = Grpc\ChannelCredentials::createSsl(
                file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
        } else {
            $ssl_credentials = Grpc\ChannelCredentials::createSsl();
        }
        $opts['credentials'] = $ssl_credentials;
        $opts['grpc.ssl_target_name_override'] = $host_override;
    } else {
        $opts['credentials'] = Grpc\ChannelCredentials::createInsecure();
    }

    if (in_array($test_case, ['service_account_creds',
                              'compute_engine_creds', 'jwt_token_creds', ])) {
        if ($test_case === 'jwt_token_creds') {
            $auth_credentials = ApplicationDefaultCredentials::getCredentials();
        } else {
            $auth_credentials = ApplicationDefaultCredentials::getCredentials(
                $args['oauth_scope']
            );
        }
        $opts['update_metadata'] = $auth_credentials->getUpdateMetadataFunc();
    }

    if ($test_case === 'oauth2_auth_token') {
        $auth_credentials = ApplicationDefaultCredentials::getCredentials(
            $args['oauth_scope']
        );
        $token = $auth_credentials->fetchAuthToken();
        $update_metadata =
            function ($metadata,
                      $authUri = null,
                      ClientInterface $client = null) use ($token) {
                $metadata_copy = $metadata;
                $metadata_copy[CredentialsLoader::AUTH_METADATA_KEY] =
                    [sprintf('%s %s',
                             $token['token_type'],
                             $token['access_token'])];

                return $metadata_copy;
            };
        $opts['update_metadata'] = $update_metadata;
    }

    if ($test_case === 'unimplemented_service') {
        $stub = new Grpc\Testing\UnimplementedServiceClient($server_address,
                                                            $opts);
    } else {
        $stub = new Grpc\Testing\TestServiceClient($server_address, $opts);
    }

    return $stub;
}

function interop_main($args, $stub = false)
{
    if (!$stub) {
        $stub = _makeStub($args);
    }

    $test_case = $args['test_case'];
    echo "Running test case $test_case\n";

    switch ($test_case) {
        case 'empty_unary':
            emptyUnary($stub);
            break;
        case 'large_unary':
            largeUnary($stub);
            break;
        case 'client_streaming':
            clientStreaming($stub);
            break;
        case 'server_streaming':
            serverStreaming($stub);
            break;
        case 'ping_pong':
            pingPong($stub);
            break;
        case 'empty_stream':
            emptyStream($stub);
            break;
        case 'cancel_after_begin':
            cancelAfterBegin($stub);
            break;
        case 'cancel_after_first_response':
            cancelAfterFirstResponse($stub);
            break;
        case 'timeout_on_sleeping_server':
            timeoutOnSleepingServer($stub);
            break;
        case 'custom_metadata':
            customMetadata($stub);
            break;
        case 'status_code_and_message':
            statusCodeAndMessage($stub);
            break;
        case 'unimplemented_service':
            unimplementedService($stub);
            break;
        case 'unimplemented_method':
            unimplementedMethod($stub);
            break;
        case 'service_account_creds':
            serviceAccountCreds($stub, $args);
            break;
        case 'compute_engine_creds':
            computeEngineCreds($stub, $args);
            break;
        case 'jwt_token_creds':
            jwtTokenCreds($stub, $args);
            break;
        case 'oauth2_auth_token':
            oauth2AuthToken($stub, $args);
            break;
        case 'per_rpc_creds':
            perRpcCreds($stub, $args);
            break;
        default:
            echo "Unsupported test case $test_case\n";
            exit(1);
    }

    return $stub;
}

if (isset($_SERVER['PHP_SELF']) &&
    preg_match('/interop_client/', $_SERVER['PHP_SELF'])) {
    $args = getopt('', ['server_host:', 'server_port:', 'test_case:',
                        'use_tls::', 'use_test_ca::',
                        'server_host_override:', 'oauth_scope:',
                        'default_service_account:', ]);
    interop_main($args);
}
